2

Ok, so I have two files which contain identical text with the exception of one line, what I'm doing is copying the differing line from the %source% file to the %target% file (which in essence is just writing the whole file line by line to the new file). The problem I'm having is that occasionally the source file will have an in-line comment denoted by an ! which does not translate to the target file. The code I am currently running is as follows:

setlocal EnableDelayedExpansion
(
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
set "line=%%b"
if defined line set "line=!line:%replace%=%replaced%!"
echo(!line!
)
) > %target%
endlocal
goto :eof

For ease the source file is a simple text file as is the target file. Tried a couple of the other "get around !" problems with delayed expansion but cannot seem to find one that works well for this situation as I don't know where in the file the ! will occur. I've tried moving the setlocal/endlocal into the for loop as well but that doesn't seem to work either.

The format of any given line in the %source% file that would cause a problem would be:

JARG 0.1000 1.2000
LINE 0.5000 1.0000 !This line tells us what is in the line
SMAP 0.0000 1.1100

Thanks for any help.

kjg5763
  • 37
  • 3

1 Answers1

3

FOR variable content containing an unescaped ! will always be corrupted if it is expanded when delayed expansion is enabled. That is because delayed variable expansion occurs after FOR variable expansion.

The trick to working with ! within FOR loops is to toggle delayed expansion on and off within the loop. This is easy when you don't have to worry about preserving variable assignments across iterations, which is exactly the situation you have.

setlocal disableDelayedExpansion
(
  for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
    set "line=%%b"
    setlocal enableDelayedExpansion
    if defined line set "line=!line:%replace%=%replaced%!"
    echo(!line!
    endlocal
  )
) > %target%
endlocal
goto :eof

Explicitly disabling delayed expansion outside of the loop is not necessary if you know that it is already disabled.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Hmm, I had tried this two different ways and once I had delayed expansion limit errors and the second time it just ran as expected but deleted the `!`. In any event, the above code works as expected, not sure what I had done incorrectly before, must have had my local flags in the wrong spot. Thank you! – kjg5763 May 23 '14 at 15:04
  • @kjg5763 - Capital E is not a problem. Batch commands are not case sensitive. I use mixed case enableDelayedExpansion for readability. – dbenham May 23 '14 at 15:21