Windows CMD 批处理:FOR /R with DelayedExpansion
Windows CMD Batch: FOR /R with DelayedExpansion
在我的桌面上,有一个名为 "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 循环永远不会迭代。
这是为什么?我错过了什么?
为什么 FOR 与 ECHO 的工作方式不同是因为批处理解析器 (cmd.exe) 对 FOR
、IF
和 REM
有特殊的 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
)
在我的桌面上,有一个名为 "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 循环永远不会迭代。
这是为什么?我错过了什么?
为什么 FOR 与 ECHO 的工作方式不同是因为批处理解析器 (cmd.exe) 对 FOR
、IF
和 REM
有特殊的 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
)