可变替代
与其他编程语言不同,在批处理文件中,在运行批处理脚本之前,变量将由其实际值替换。换句话说,当命令处理器将脚本读入内存时,而不是稍后运行脚本时,将进行替换。
这使得变量可以作为脚本中的命令使用,也可以作为脚本中其他变量名称的一部分使用。此上下文中的脚本是代码的行或块,用圆括号括起来:()
。
但是这种行为确实意味着你无法在块内更改变量的值!
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
ECHO %VAR%
SET VAR=Goodbye
)
将打印
Hello
Hello
因为(如你所见,在观察命令窗口中运行的脚本时),它被评估为:
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
echo Hello
SET VAR=Goodbye
)
在上面的示例中,当脚本被读入内存时,ECHO
命令被评估为 Hello
,因此脚本将永远回显 Hello
,但是通过脚本进行了多次传递。
实现更传统变量行为(在脚本运行时扩展变量)的方法是启用延迟扩展。这涉及在循环指令之前将该命令添加到脚本中(通常是 FOR 循环,在批处理脚本中),并在变量名称中使用感叹号(!)而不是百分号(%):
setlocal enabledelayedexpansion
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
echo !VAR!
SET VAR=Goodbye
)
endlocal
将打印
Hello
Goodbye
语法%%a in (1,1,2)
使循环运行 2 次:第一次,变量承载其初始值’Hello’,但是在第二次循环中循环 - 执行第二个 SET 指令作为第一次传递的最后一个动作 - 这已经改为修改后的值’Goodbye’。
高级变量替换
现在,一种先进的技术。使用 CALL
命令允许批处理命令处理器扩展位于脚本同一行的变量。通过重复使用 CALL 和修饰符,可以实现多级扩展。
这在例如 FOR 循环中很有用。如下例所示,我们有一个编号的变量列表:
"c:\MyFiles\test1.txt" "c:\MyFiles\test2.txt" "c:\MyFiles\test3.txt"
我们可以使用以下 FOR 循环实现此目的:
setlocal enabledelayedexpansion
for %%x in (%*) do (
set /a "i+=1"
call set path!i!=%%~!i!
call echo %%path!i!%%
)
endlocal
输出:
c:\MyFiles\test1.txt
c:\MyFiles\test2.txt
c:\MyFiles\test3.txt
请注意,变量 !i!
首先扩展到其初始值 1,然后生成的变量%1 扩展到其实际值 c:\MyFiles\test1.txt
。这是变量 i
的双重扩展。在下一行,i
再次双重展开,使用 CALL ECHO
命令和%%
变量前缀,然后打印到屏幕上(即显示在屏幕上)。
在每次连续通过循环时,初始数量增加 1(由于代码 i+=1
)。因此,它在第二次通过环路时增加到 2
,在第三次通过时增加到 3
。因此,每次通过时,回显到屏幕的字符串都会改变。