我尽量避免使用 SETLOCAL enabledelayedexpansion ... ENDLOCAL
,因为通常我想要设置或修改一些变量,并且希望新值在脚本的其他区域或批处理脚本结束后仍然可用(SETLOCAL|ENDLOCAL 将忘记“SETLOCAL”部分中任何新变量或变量更改。有时这很方便,但对我来说,通常不是。
目前我使用@Zuzel描述的方法,但在我知道这个方法之前,我曾经使用过这个方法,它非常相似(但看起来有点更加复杂):
for /F "usebackq delims=" %%f in (`echo set "a=^%a:%b%=%c%^%"`) do @%%f
示例脚本:
@echo off
set a=The fat cat
set b=fat
set c=thin
@echo.
@echo before: "%a%"
@echo replace "%b%" with "%c%" in "%a%" using for:
for /F "usebackq delims=" %%f in (`echo set "a=%%a:%b%=%c%%%"`) do @%%f
@echo after for: "%a%"
goto :EOF
运行脚本后的输出结果:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using for:
after for: "The thin cat"
我喜欢这种方法,因为你可以使用修改后的变量调用外部程序(或内部命令),并捕获和处理命令的输出(逐行)。
但是,在大多数情况下,包括您描述的情况下,Zuzel的方法更简单、更干净。
注意:
这两种方法(当然还有SETLOCAL enabledelayedexpansion ... ENDLOCAL
)只有在批处理脚本内运行时才能正确工作。如果您尝试直接在命令提示符窗口中使用这两种方法(“call”或“for”),则得到的结果与从脚本运行的输出不同。
例如,将此作为脚本运行:
@echo off
set a=The fat cat
set b=fat
set c=thin
set d=calico
set e=sleepy
@echo.
@echo before: "%a%"
@echo.
@echo replace "%b%" with "%c%" in "%a%" using call:
call set a=%%a:%b%=%c%%%
@echo after call: "%a%" ("%b%" to "%c%")
@echo.
@echo replace "%c%" with "%d%" in "%a%" using for:
for /F "usebackq delims=" %%f in (`echo set "a=%%a:%c%=%d%%%"`) do @%%f
@echo after for: "%a%" ("%c%" to "%d%")
@echo.
@echo replace "%d%" with "%e%" in "%a%" using call:
call set a=%%a:%d%=%e%%%
@echo after call: "%a%" ("%d%" to "%e%")
运行脚本后的输出结果:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using call:
after call: "The thin cat" ("fat" to "thin")
replace "thin" with "calico" in "The thin cat" using for:
after for: "The calico cat" ("thin" to "calico")
replace "calico" with "sleepy" in "The calico cat" using call:
after call: "The sleepy cat" ("calico" to "sleepy")
现在,请直接在命令提示符窗口中运行这些命令:
c:\>
c:\>set a=The fat cat
c:\>set b=fat
c:\>set c=thin
c:\>set d=calico
c:\>set e=sleepy
c:\>
c:\>@echo.
c:\>@echo before: "%a%"
before: "The fat cat"
c:\>@echo.
c:\>
c:\>@echo replace "%b%" with "%c%" in "%a%" using call:
replace "fat" with "thin" in "The fat cat" using call:
c:\>call set a=%%a:%b%=%c%%%
c:\>@echo after call: "%a%" ("%b%" to "%c%")
after call: "%The thin cat%" ("fat" to "thin")
c:\>
c:\>@echo.
c:\>@echo replace "%c%" with "%d%" in "%a%" using for:
replace "thin" with "calico" in "%The thin cat%" using for:
c:\>for /F "usebackq delims=" %f in (`echo set "a=%%a:%c%=%d%%%"`) do @%f
c:\>@echo after for: "%a%" ("%c%" to "%d%")
after for: "%%The calico cat%%" ("thin" to "calico")
c:\>
c:\>@echo.
c:\>@echo replace "%d%" with "%e%" in "%a%" using call:
replace "calico" with "sleepy" in "%%The calico cat%%" using call:
c:\>call set a=%%a:%d%=%e%%%
c:\>@echo after call: "%a%" ("%d%" to "%e%")
after call: "%%%The sleepy cat%%%" ("calico" to "sleepy")
c:\>
检查命令提示符窗口中的前后输出行:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using call:
after call: "%The thin cat%" ("fat" to "thin")
replace "thin" with "calico" in "%The thin cat%" using for:
after for: "%%The calico cat%%" ("thin" to "calico")
replace "calico" with "sleepy" in "%%The calico cat%%" using call:
after call: "%%%The sleepy cat%%%" ("calico" to "sleepy")
请注意,替换是正确的,但是请注意,在直接在命令提示符窗口运行这些命令时,每次进行替换时都会在预期值之前和之后添加一组“%”(百分号)。因此,直接在命令提示符窗口中测试任何这些方法都会变得更加困难。