Windows CMD 批处理脚本 - 如何避免切割标记“!”在循环

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

我有 XML 个文件 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>

我需要在 CMD 中的批处理脚本中更改值。

@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

输出 - 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>

安装路径中的更改值已正确更改,但 myPassword 中的值剪切字符“!”。如何让它不剪掉我的标记“!”

通过在设置值之前启用延迟扩展,您自己有效地削减了 ! 扩展字符。

要保留 ! 值,请在分配值之前禁用延迟扩展,此时您可以启用它而不会丢失 !

一个简短的例子:

@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

延迟扩展是执行之前发生的最后一件事,即使在 for 元变量扩展之后也是如此。当现在这样一个 for 元变量包含一个带有感叹号的值时,这将被延迟扩展所消耗。解决方案是切换延迟扩展,以便仅在需要时启用它,否则禁用:

@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