AquaAlex February 2016

Issue with Windows Batch Script - replace

Hi have a for loop that I use to get entries out of a lsit of drives to loop through, for each drive I loop through entries in a file, this all works. But then what I am trying to do is finding the entry from the file (which is a file name and path without the drive letter and the first folder (parent folder named %_TAG%)

Ok so far so good, now what I want to do is replace the extension of the file with a r (*.w or *.p or *.cls must become *.r)

But for some reason my command does not work (set str=!str:.w=.r!) I have tried replacing the ! with %

I have tried various things and still stuck. Here is my complete batch file. It reads in a file with a list of partial path and file names. I even tried using a function to do renaming

    @echo on
    setlocal enabledelayedexpansion
    set _TAG=TST
    set /p _INFILE="Enter Filename to use for investigation: "
    set _INFILE=%CD%\%_INFILE%
    set /p _TAG="To which environment did you deploy? (TST / LIV): "
    if /i "%_TAG%"=="LIV" (
      set _drive=M O P R S Y X
    ) else (
      set _drive=M T X
    echo We will use code in the: %_TAG% folder and file: %_INFILE% and drives: %_drive%
    set /p _continue="Do you wish to continue (Y/N): "
    if /i "%_continue%"=="N" goto :eof
    echo We will use code in the: %_TAG% folder and file: %_INFILE% and drives: %_drive%  1>> %_INFILE%.%_TAG%.rlog 2>&1
    for %%j in (%_drive%) do (
        echo ...
        echo investigating: %%j:\%_TAG%\ 1>> %_INFILE%.%_TAG%.rlog 2>&1
        cd %%j:\%_TAG%\
        for /f %%i in (%_INFILE%) DO  ( 
            set "string=%%i"
            call:mySetPathFunc !string! "/"    "\"
            call:mySetPathFunc !string! ".w"   ".r"
            call:mySetPathFunc !string! ".p"   ".r"
            call:mySetPathFunc !string! ".cls" ".r"
            if exist %%j:\%_TAG%\!string! (
                echo I found you in correct f        


Magoo February 2016

Generation 955 of the "delayedexpansion" problem.

Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).

Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.

Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.

Where flags are involved, the situation changes again. set "flag=" will ensure a flag is cleared. set "flag=somethingelse" will ensure it is set (the value is not relevant.) Using if defined flag (doiftrue) else (doiffalse) works on the run-time (current) status of flag - not the parse-time value.

Look for hundreds of items about delayedexpansion on SO for solutions.

Post Status

Asked in February 2016
Viewed 3,729 times
Voted 5
Answered 1 times


Leave an answer