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

五迷三道 提交于 2020-06-01 07:41:08

问题


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 "!"


回答1:


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



回答2:


You are effectively cutting the ! expansion character yourself by enabling delayed expansion prior to setting the value.

To preserve the ! value, disable delayed expansion until after values have been assigned, at which point you can then Enable it without losing !

A short example:

@Echo Off
    For %%A in ("Installpath>Example" "Installpath>of" "Installpath>Expansion Preservation!") Do Call :Assign "%%~A"
    Setlocal EnableDelayedExpansion
    For /L %%I in (1,1,%Count%) Do Echo(!Line[%%I]!
    Pause
Exit /B

:Assign
    SetLocal DisableDelayedExpansion
    Set "Line=%~1"
    Set "Line=%Line:Installpath>=%"
    Set /A Count+=1
    Endlocal & Set "Line[%Count%]=%Line%" & Set "Count=%Count%"
Exit /B


来源:https://stackoverflow.com/questions/61818032/windows-cmd-batch-script-how-to-avoid-cutting-the-mark-in-the-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!