在批处理文件中显示文本文件中的行

时间:2010-02-24 11:53:45

标签: batch-file

文件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

有什么想法吗?

1 个答案:

答案 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%