我正在编写一个Batch脚本来编译一个文件列表作为字符串(“file1.txt file2.txt filr3.txt ...”)。我这样做是因为我想运行一个需要传入要处理的文件列表的应用程序。
所有文件都在同一个文件夹中。
当我运行以下代码时:
FOR /f "tokens=*" %%M IN ('dir * /b') DO (
SET files=%files% %%M
)
ECHO END %files%
最后的回显仅提供最后处理的文件,而不是整个列表。我的实施有什么问题?
感谢您提供任何帮助
答案 0 :(得分:4)
您需要使用延迟扩展:
setlocal enabledelayedexpansion
for /f "tokens=*" %%M in ('dir * /b') do (
set files=!files! %%M
)
echo END %files%
您可以在help set
:
延迟环境变量扩展对于四处走动非常有用 一条线发生的当前扩张的局限性 读取文本,而不是执行时。以下示例 演示了立即变量扩展的问题:
由于BOTH IF语句中的set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
%VAR%
,永远不会显示消息 在读取第一个
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
设置为找到的最后一个文件。
此外,您不应该使用for /f
来迭代dir
输出,因为这可能会以微妙的方式破坏。您需要对包含空格的文件名进行特殊处理,并且它会使用光栅字体和Unicode。基本上你说的是“嘿,我正在运行一个命令,将其输出标记为转换为当前的OEM代码页,并尝试使用它而不是仅仅要求for
迭代文件”:
for %%M in (*) do ...