在块语句(a parenthesised series of statements) 中,整个块被解析并然后执行。块中的任何%var% 都将替换为该变量的值在分析块时 - 在块执行之前 - 同样适用于FOR ... DO (block)。
因此,IF (something) else (somethingelse) 将在遇到IF 时使用%variables% 的值执行。
解决此问题的两种常见方法是 1) 使用 setlocal enabledelayedexpansion 并使用 !var! 代替 %var% 来访问 var 的更改值或 2) 调用子例程以使用改变了值。
因此请注意CALL ECHO %%var%% 的使用,它显示var 的更改值。
您的代码包含两个单独的变量,称为 f。
第一个是称为f 并由%%f 引用的循环控制“元变量”。
第二个是公共环境变量f,由set "f=..."语句建立。这个变量可以通过在block 中使用%f% 但是 来访问,它似乎保留了它在解析控制for 时的值(实际上,任何%var% 都是在解析时被 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 和加倍%s,最后一行将显示!f! - 一个文字,因为在delayedexpansion 模式之外,! 只是另一个对cmd没有特殊意义的字符。