Windows CMD批处理:使用延迟扩展的FOR /R

4
在我的桌面上有一个名为“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"

似乎在 ECHO !test! 行中会展开 !test!,但在 FOR /R !test! 行中不会展开,变成了 !test!。因为这当然不是一个有效的路径,所以 FOR /R 循环永远不会遍历。
这是为什么?我漏掉了什么吗?
1个回答

5
FOR 命令与 ECHO 命令不同的原因是批处理解析器 (cmd.exe) 对 FOR、IF 和 REM 有特殊的 解析规则。因此,延迟扩展对于参数无效,只对圆括号内的参数有效。只有百分号扩展对参数有效,因为解析器在切换到特殊的 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
)

那很有趣(但不幸的是)。谢谢! - TSmith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接