嵌套批处理 for 循环
下面的嵌套 for 循环让我抓狂(在 Windows 7 上):
@echo off
SetLocal EnableDelayedExpansion
set TESTDIRS=fast mid slow
set TD=src\test\resources\testsuite
for %%d in (%TESTDIRS%) do (
set CTD=%TD%\%%d
echo CTD: !CTD!
REM Echos the expected path
echo CTD: %CTD%
REM Echos nothing -- understandable
for /R !CTD! %%f in (*.fs) do (echo %%f)
REM Echos nothing -- why?
for /R src\test\resources\testsuite\fast %%f in (*.fs) do (echo %%f)
REM Echos expected files
)
我尝试了各种解决方案,包括禁用 DelayedExpansion、调用语句等,但我从未让内部循环正常工作。我知道我可以通过子例程调用来替换内部循环,但必须有一种方法可以使其与嵌套循环一起使用。
The following nested for-loop drives me mad (on Windows 7):
@echo off
SetLocal EnableDelayedExpansion
set TESTDIRS=fast mid slow
set TD=src\test\resources\testsuite
for %%d in (%TESTDIRS%) do (
set CTD=%TD%\%%d
echo CTD: !CTD!
REM Echos the expected path
echo CTD: %CTD%
REM Echos nothing -- understandable
for /R !CTD! %%f in (*.fs) do (echo %%f)
REM Echos nothing -- why?
for /R src\test\resources\testsuite\fast %%f in (*.fs) do (echo %%f)
REM Echos expected files
)
I tried various solutions involving disabling DelayedExpansion, call-statements and whatnot, but I never got the inner loop working. I know that I could replace the inner loop by a subroutine call, but there gotta be a way to make it work with nested loops.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
根据 FOR 帮助,
FOR /R
“遍历以 [drive:]path 为根的目录树,在树的每个目录中执行 FOR 语句。”可能有争议的是“走”这个词。在我看来,只有迈出第一步,步行才会发生,如果没有迈出一步,那么就不会发生步行。由于在这种情况下,步行从目录“fast”开始并且没有子目录,因此不可能执行第一步。
但是,如果将第二个 FOR 更改为:
那么回显的结果是:
这就是 OP 正在寻找的“FOR”吗?如果是这样,那是因为现在有一个地方可以递归,那就是父目录。
(注:在此测试中,fast、mid、slow 目录分别包含一个文件,分别为 F1.fs、F2.fs 和 F3.fs。)
According to FOR help,
FOR /R
"Walks the directory tree rooted at [drive:]path, executing the FOR statement in each directory of the tree."What may be at issue is the word 'walk'. It seems to me that a walk doesn't occur until one takes the first step and if no step occurs then no walk occurs. Since in this case the walk begins in directory 'fast' and there are no subdirectories, no first step is possible.
However, if you change the second FOR to:
then the result echoed is:
Is that what OP was looking 'FOR'? If so, it would be because now there is someplace to recurse from, that being the parent dir.
(Note: in this test the dirs fast, mid, slow contained one file each, F1.fs, F2.fs and F3.fs, respectively.)
引用Malte Schwerhoff的回答
如果你不想重复B,你可以简单地添加“if”语句
输出:
Quote Malte Schwerhoff's Answer
If you don't want to repeat B, you can simply add "if" statement
output:
这并不明显!就是FOR的特殊解析!
FOR 命令在转义/特殊字符阶段(用于检测括号)之后直接进行解析,但因此您不能使用延迟或 %%var 扩展作为参数。
这也是行不通的:
不将 a、b 和 c 设置为分隔符,而是设置 !,改为 c、h、a 和 r。
编辑:在括号内,延迟扩展确实按预期工作,但是:
我希望您必须使用函数来解决您的问题。
It's not obvious! It's the special parsing of FOR!
A FOR command is parsed directly after the escape/special character phase (for detecting the parenthesis), but as a result you can't using delayed or %%var expansion as parameters.
And also this can't work:
does not set a, b and c as delims, but !, c, h, a and r instead.
EDIT: Within the parentheses the delayed expansion does work as expected however:
I would expect that you have to use a function to solve your problem.
如果您使用
pushd !CTD!
和popd
,并让FOR /R
默认使用当前目录会怎样?What if you used
pushd !CTD!
andpopd
, and letFOR /R
default to using the current directory?因为没有人提到它,所以这里是使用批处理子例程和 CALL 命令的解决方案。
我知道 GOTO 不是很流行,但是批处理文件最初设计是为了使用标签来控制流程。带括号的控制结构语法是后来添加的,这个问题是它崩溃的一个例子。这个问题很适合批处理子程序。
Because nobody has mentioned it, here is the solution using batch subroutines and the
CALL
command.I know GOTO is not very popular, but batch files were originally designed to use labels for control flow. The parenthetized control structure syntax was added later, and this question is an example of where it breaks down. The problem lends itself well to batch subroutines.
仅举一个有效的嵌套循环的示例:
输出(至少在 Windows 7 上)是
这支持了 jeb 的观察,即循环中的变量扩展如果出现在括号内,则可以工作(即使没有延迟扩展)。
Just to give an example of a nested loop that works:
The output (at least on Windows 7) is
This supports jeb's observation that variable expansion in loops works if they occur inside parenthesis (even without delayed expansion).