Windows CMD批处理:具有DelayedExpansion的FOR / R

时间:2015-05-19 20:06:27

标签: batch-file for-loop command-line cmd variable-expansion

在我的桌面上,有一个名为“test”的文件夹。在此文件夹中有两个文件,“file1.txt”“file2.txt”

看看这个简单的批处理脚本:

@ECHO OFF

SET test="C:\Users\Tyler\Desktop\test"

ECHO %test%
FOR /R %test% %%F IN (*) DO (
    ECHO %%F
)

正如您所料,它输出以下内容:

"C:\Users\Tyler\Desktop\test"
C:\Users\Tyler\Desktop\test\file1.txt
C:\Users\Tyler\Desktop\test\file2.txt

现在看看这个变化:

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

SET test="C:\Users\Tyler\Desktop\test"

ECHO !test!
FOR /R !test! %%F IN (*) DO (
    ECHO %%F
)

ENDLOCAL

我希望它的输出没有什么不同。但是,这是:

"C:\Users\Tyler\Desktop\test"

似乎!test!ECHO !test!行展开,但在FOR /R !test!行不展开,只变为!test!。因为那当然不是有效路径,所以FOR / R循环永远不会迭代。

这是为什么?我错过了什么?

1 个答案:

答案 0 :(得分:5)

为什么FOR的工作方式与ECHO不同,是因为批处理解析器(cmd.exe)对FORIFREM有特殊的parsing rules

因此,延迟扩展不适用于此处的参数,仅适用于括号内的参数。

只有百分比扩展适用于参数,因为解析器在切换到特殊FOR解析器规则之前执行百分比扩展阶段。

如果你不能使用百分比扩展,因为你在一个块内,你可以将代码移动到一个自己的函数并调用它。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET test="C:\Users\Tyler\Desktop\test"

ECHO !test!
call :doMyLoop test
exit /b

:doMyLoop
set "arg=!%1!"
FOR /R %arg% %%F IN (*) DO (
    ECHO %%F
)