文件test.cmd:
name=dummy
for /f "eol=; tokens=1 delims=," %%i in (list.txt) do (
echo i: %%i
set name=%%i
echo name: %name%)
文件list.txt包含这一行(每行一个名称):
John
Tom
Erica
Sara
每次启动此批次时,我都会收到此输出:
i: John
name: dummy
i:T om
name: dummy
i: Erica
name: dummy
i: Sara
name: dummy
似乎变量名称未被赋值为%%i
有什么想法吗?
答案 0 :(得分:1)
你陷入了不使用延迟扩展的旧陷阱。
要快速修复,只需输入
即可setlocal enabledelayedexpansion
在批量文件中循环之前,使用!name!
代替%name%
。
CMD在解析命令时扩展变量。在这个意义上的命令是单行或“块”,用括号分隔。完整的for
循环仅被解析一次,并且在该阶段%name%
被替换为该点处的值,即"dummy"
。另一方面,延迟扩展使用!
而不是%
来分隔变量名称,然后在执行命令之前扩展变量。
每当您在带括号的块中设置变量并且再次在同一块中使用其值时,您需要使用延迟扩展。 help set
还有一些关于此的信息:
延迟环境变量扩展 是有用的绕过 目前扩张的局限性 当一行文字出现时会发生这种情况 读取,而不是在执行时。该 以下示例演示了 立即变量的问题 扩展:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
永远不会显示消息,因为 两个
%VAR%
语句中的IF
是 在第一个IF
时替换 声明是从逻辑上读的 包括IF
的正文 复合陈述。那么IF
复合语句里面是 真的比较“之前”和“之后” 永远不会平等。同样的, 以下示例将不起作用 预期:set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
因为不会建立一个列表 但是,当前目录中的文件 而只是设置
LIST
变量到找到的最后一个文件。 同样,这是因为%LIST%
是 在FOR
时扩展一次 声明被阅读,并在那时LIST
变量为空。所以 我们正在执行的实际FOR
循环是:for %i in (*) do set LIST= %i
只是将
LIST
设置为 找到最后一个文件。延迟环境变量扩展 允许你使用不同的 字符(感叹号)到 扩展环境变量 执行时间处理时间。如果延迟变量 扩展已启用,以上 例子可以写成如下 按预期工作:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%