问题
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