在一个代码块语句中,整个代码块会被解析后再执行。在代码块中的任何
%var%
都将被替换为代码块解析时该变量的值(在代码块执行之前) - 对于
FOR ... DO (block)
同样适用。
因此,
IF (something) else (somethingelse)
会使用遇到
IF
时的
%variables%
值来执行。
克服这点常见的方法有两种:1)使用
setlocal enabledelayedexpansion
并使用
!var!
替代
%var%
来访问更改后的
var
值;2)调用子程序以使用更改后的值进行进一步处理。
注意使用
CALL ECHO %%var%%
显示更改后的
var
值。
你的代码包含两个名为
f
的不同变量。
第一个是循环控制“元变量”称为
f
,可以通过
%%f
引用。
第二个是由
set "f=..."
语句建立的普通环境变量
f
。可以使用
%f%
访问此变量,但在代码块内,它似乎保留了控制
for
解析时的值(实际上,任何
%var%
在解析时都被替换为该变量在那个时间的值)。
metavariables
不能用于字符串操作语句,例如子字符串或替换,只能使用普通环境变量来执行这些操作,因此需要将元变量
f
的值分配给环境变量
f
,然后对环境变量
f
执行字符串替换任务。
当然,关键是必须使用
delayedexpansion
和
!var!
语法在块内访问修改后的环境变量的值。
因此,
setlocal enabledelayedexpansion
for...%%f...do (
echo %%f
set "f=%%f"
set "f=!f:\=/!"
echo !f!
)
echo just for demonstration %f% !f! %%f
这以所需方式设置了f
的值(当然,您始终可以更改名称以避免混淆...)
最后一行仅用于显示通过f
获取的最终值可以作为%f%
或!f!
在循环外部访问,而%%f
是超出上下文范围并显示为%f
。
另一种无需使用delayedexpansion
的方法是
for...%%f...do (
echo %%f
set "f=%%f"
call set "f=%%f:\=/%%"
call echo %%f%%
)
echo just for demonstration %f% !f! %%f
不同之处在于使用call
命令并将%
符号翻倍,最后一行将显示!f!
,作为一个字面值。因为在delayedexpansion
模式之外,!
只是另一个没有特殊含义的字符。