Jeremy Rowler
Jeremy Rowler

Reputation: 387

How to output exclamation mark with EnabledDelayedExapnsion?

I am working on editing an XML file, and approximately the first 10 lines are comments. And for xml comments are in the form

<!--  COMMENT HERE   -->

But when using my code it does not output that ! mark, which screws up the comments in the xml. I understand that the ENABLEDELAYEDEXPANSION is doing this because it thinks the exclamation mark is expanding a variable. How could I get this to work?

Here is my code below

setlocal ENABLEDELAYEDEXPANSION

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line = !line!+1 
    if !line!==39 (echo REPLACED TEXT39>>%tempfile%
)else if(!line!==45 (echo REPLACED TEXT45>>%tempfile%
)else (echo %%a>>%tempfile%
))

EDIT1 Basically what it is supposed to do is output each line as it is, unless it is line 39 or 45. It works, except the ! marks in the comments don't get outputted and they are not comments anymore.

EDIT2

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
setlocal ENABLEDELAYEDEXPANSION
    set /a !line! +=1
echo !line!
    if !line!==39 (
echo REPLACED TEXT39>>%tempfile%
endlocal
)else if !line!==45 (
echo REPLACED TEXT45>>%tempfile%
endlocal
)else (
endlocal
setlocal DISABLEDELAYEDEXPANSION
echo %%a>>%tempfile%
endlocal
))

Here is the latest code I have been using. It works the best, but now the problem is that the variable "line" is not getting updated. I have a feeling that it is because of the "endlocal". The only problem is that I need the "endlocal" there otherwise I get an error

Maximum setlocal recursion level reached.

The problem is, I need to alternate between enableddelayedexpansion and disabledelayedexpansion so that my exclamation marks show up properly. But to do that I need to keep up with the "endlocal" calls which i think is messing up my line variable. Any thoughts?

Upvotes: 1

Views: 185

Answers (1)

jeb
jeb

Reputation: 82307

You can't output the exclamation mark this way.

The exclamation mark is part of the content of %%a but while delayed expansion is enabled you can't access it, as it will be parsed after the %%a is epanded.

So you need to disable delayed expansion at all or temporary.

A sample for temporary disabling it

setlocal ENABLEDELAYEDEXPANSION

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line = !line!+1 
    if !line!==39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if !line!==45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      setlocal DisableDelayedExpansion
      echo %%a>>%tempfile%
      endlocal
    )
)

Or you don't use it at all, then you only need to get the if line=42 part working.
This uses the fact that modulo by 0, will produce an error (which is suppressed by 2>nul) and the variable stays unchanged, in this case they stay undefined.

setlocal DisableDelayedExpansion
set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line+=1
    set "notLine39="
    set /a "notLine39=1%%(line-39)" 2>nul
    set "notLine45="
    set /a "notLine45=1%%(line-45)" 2>nul

    if not defined line39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if not defined line45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      setlocal DisableDelayedExpansion
      echo %%a>>%tempfile%
      endlocal
    )
)

Edit: Added explanation to your changed question
This uses the toggling delayed expansion technic, described in SO: Batch files: How to read a file?
The trick is to be in disabledDelayedExpansion when transfering %%a to text, then switching to enabledDE and be able to use the extended syntax.
But don't forget the endlocal before the next loop starts.

setlocal DisableDelayedExpansion
set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line+=1
    set "text=%%a"
    setlocal EnableDelayedExpansion
    if !line!==39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if !line!==45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      echo %%a>>%tempfile%
    )
    endlocal
)

Upvotes: 5

Related Questions