嵌套批处理循环

Mal*_*off 20 windows loops for-loop nested batch-file

以下嵌套的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
)
Run Code Online (Sandbox Code Playgroud)

我尝试了各种解决方案,包括禁用DelayedExpansion,call-statements和诸如此类的东西,但我从来没有让内循环工作.我知道我可以通过子程序调用替换内部循环,但是必须有一种方法可以使它与嵌套循环一起工作.

Mal*_*off 25

只是举一个有效的嵌套循环的例子:

@echo off
SetLocal

set B=alpha beta gamma
set A=eins zwo

FOR %%b in (%B%) do (
  FOR %%a in (%A% %%b) DO (
    echo %%b -^> %%a
  )
)
Run Code Online (Sandbox Code Playgroud)

输出(至少在Windows 7上)是

alpha -> eins
alpha -> zwo
alpha -> alpha
beta -> eins
beta -> zwo
beta -> beta
gamma -> eins
gamma -> zwo
gamma -> gamma
Run Code Online (Sandbox Code Playgroud)

这支持了jeb的观察,即如果它们出现在括号内(即使没有延迟扩展),循环中的变量扩展也可以工作.

  • 嗨,我使用了您的示例,但它会在最后一次陡峭的情况下打印 %%b 而不是 %%a,我通过在内循环中仅在 (%A%) 中使用 FOR %%a 来解决它 (3认同)

Rya*_*ose 12

因为没有人提到它,所以这里是使用批处理子程序和CALL命令的解决方案.

@echo off

set TESTDIRS=fast mid slow
set TD=src\test\resources\testsuite

for %%d in (%TESTDIRS%) do call :process_testdir %%d
goto :eof

:process_testdir
set CTD=%TD%\%1
echo CTD: %CTD%
    REM Echos the expected path

for /R %CTD% %%f in (*.fs) do (echo %%f)
    REM Echos as expected

goto :eof
Run Code Online (Sandbox Code Playgroud)

我知道GOTO不是很受欢迎,但批处理文件最初设计用于控制流程的标签.后面添加了括号中的控制结构语法,这个问题就是它出现故障的一个例子.这个问题非常适合批处理子程序.


Ben*_*igt 11

如果你使用的pushd !CTD!popd,并让FOR /R默认使用当前目录?

  • 这是一种以不同方式解决特定问题的变通方法。它没有解释如何正确嵌套 for 循环(即不回答问题)。我想用不同的用例嵌套 for 循环,在该用例中,此解决方法不能解决问题,并通过谷歌搜索“批量嵌套 for 循环”来到这里。-1 从我。 (4认同)

jeb*_*jeb 5

这不明显!这是FOR的特殊解析!
FOR命令是转义/特殊字符相(用于检测括号)后直接分析,但其结果是无法使用延迟或%% VAR膨胀作为参数.

FOR %%a in (%%%%B) do (
  FOR %%a in (1) DO ( <<< this %%a will not replaced with %%B
      echo %%a - shows 1, because %%a is the name of the inner variable
      echo %%B - doesn't work
  )
)
Run Code Online (Sandbox Code Playgroud)

而且这也行不通:

set chars=abc
FOR /F "delims=!chars!" %%N in (bla) DO ....  
Run Code Online (Sandbox Code Playgroud)

没有将a,bc设置为delims,但是!,c,h,ar代替.

编辑:在括号内,延迟扩展确实按预期工作:

set var=C:\temp
For %%a in (!var!) DO echo %%a
Run Code Online (Sandbox Code Playgroud)

我希望你必须使用一个函数来解决你的问题.

  • 抱歉,但我想您只能使用 Ben Voigt 的 PUSHD 解决方案。通过扩展,这似乎是不可能的,因为内部循环的路径仅在第一个括号的开头扩展一个, (2认同)