Search code examples
windowsbatch-filecmddelayedvariableexpansion

Windows CMD Batch Script - how to avoid cutting the mark "!" in the loop


I have XML file myConfig.xml.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<test1.test.com id="valueTest1"/>
<test2.test.com id="valueTest1"/>
<test3.test.com id="valueTest1"/>
<installpath>C:\Temp\TESTxyz</installpath>
<userInput>
<entry key="myPassword" value="Qwerty123!"/>
<entry key="myLogin" value="John"/>
</userInput>

I need in CMD in batch script change value in .

@echo off
setlocal EnableDelayedExpansion
set newValueInstallpath="D:\Work"

(for /F "delims=" %%a in (myConfig.xml) do (
set "line=%%a"
set "newLine=!line:installpath>=!"
if "!newLine!" neq "!line!" (
    set "newLine=<installpath>%newValueInstallpath%</installpath>"
)
echo !newLine!
)) > NEW_myConfig.xml

OUTPUT - NEW_myConfig.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<test1.test.com id="valueTest1"/>
<test2.test.com id="valueTest1"/>
<test3.test.com id="valueTest1"/>
<installpath>D:\Work</installpath>
<userInput>
<entry key="myPassword" value="Qwerty123"/>
<entry key="myLogin" value="John"/>
</userInput>

Change value in installpath is correctly changed BUT value in myPassword cut character "!". How to make it not cut my mark "!"


Solution

  • Delayed expansion is the last thing that happens prior to execution, even after expansion of for meta-variables. When now such a for meta-variable contains a value with an exclamation mark this is going to be consumed by delayed expansion. The solution is to toggle delayed expansion so that it is enabled only when it is needed and disabled otherwise:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "newValueInstallpath=D:\Work"
    
    (for /F "usebackq delims=" %%a in ("myConfig.xml") do (
        set "line=%%a"
        setlocal EnableDelayedExpansion
        set "newLine=!line:installpath>=!"
        if "!newLine!" neq "!line!" (
            set "newLine=<installpath>!newValueInstallpath!</installpath>"
        )
        echo(!newLine!
        endlocal
    )) > "NEW_myConfig.xml"
    
    endlocal