为什么循环没有按预期运行?

时间:2015-10-26 19:30:28

标签: batch-file goto delayedvariableexpansion

我有像E:\Backups\code\Hazard\test1 ... testn

这样的文件夹

在这些测试文件夹中,例如E:\Backups\code\Hazard\test1\it0 ... itn

根文件夹是代码运行的E:\Backups\code

以下代码在每个子文件夹上运行,并将summary.ymlit0文件夹复制到最新的it(n)文件夹。

为什么代码只针对test1文件夹运行然后挂起?

setlocal ENABLEDELAYEDEXPANSION

set root=%cd%
for /D %%X in (%root%\*) do (
    echo %%X
    cd  %%X

    for /D /r %%b in (*) do ( 
        cd  %%b

        echo %%b

        for /f "tokens=1,2,*" %%a in ('robocopy . . file.txt /l /nocopy /is /s /nc /ns /ts /ndl /njh /njs ^| sort /r') do set "lastFolder=%%~dpc" & goto :done
:done
        echo Last folder : %lastFolder%

        for /d    %%j in (*) do  (
            if /i "%%~nj"=="it0" COPY %%j\summary.yml %lastFolder% 
        )
        cd ..
    )
)

2 个答案:

答案 0 :(得分:1)

我不确定 robocopy 的行应该做什么。看起来这个命令用于获取当前目录中最后一个子目录的名称。

也许这段代码效果更好。但我无法测试它。

setlocal EnableDelayedExpansion
set "root=%cd%"

for /D %%X in ("%root%\*") do (
    echo %%X
    cd "%%~X"

    for /D /r %%b in (*) do (
        cd "%%~b"
        echo %%b

        call :GetLastFolder

        echo Last folder : !lastFolder!

        for /d %%j in (*) do (
            if /i "%%~nj"=="it0" copy "%%j\summary.yml" "!lastFolder!"
        )
        cd ..
    )
)
goto :EOF

:GetLastFolder
for /f "tokens=1,2,*" %%a in ('robocopy . . file.txt /l /nocopy /is /s /nc /ns /ts /ndl /njh /njs ^| sort /r') do set "lastFolder=%%~dpc" & goto :EOF
goto :EOF

至少有必要引用带有感叹号的环境变量lastFolder而不是百分号来真正根据需要使用延迟扩展。

goto :EOF退出子例程,导致继续在call :GetLastFolder下面的行。

在主要代码之后还有一个goto :EOF或者exit /B,以避免在最多外部 for 循环完成后再次执行子例程的代码。此goto :EOF导致退出此批处理文件的处理。

要了解使用的命令及其工作原理,请打开命令提示符窗口,至少执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • call /?
  • for /?
  • goto /?
  • set /?

答案 1 :(得分:1)

代码中存在两个主要问题:

  • 如果在for循环内使用setlocal enabledelayedexpansion,则取消循环
  • 如果在代码块(括号内的代码)中设置变量,要在同一代码块中检索变量的值,需要延迟扩展,使用%var%启用它并更改使用的语法将变量中的值从!var!检索到goto

但是

  • 可以移除for,如previous answer
  • 所示
  • 不需要延迟扩展。不要将@echo off setlocal enableextensions disabledelayedexpansion rem E:\Backups\ code \ Hazard \ test1 \ it0 ... itn rem ^root ^ %%X ^ %%Y ^ %%~dpc for /D %%X in ("*") do for /D %%Y in ("%%~fX\*") do for /f "tokens=1,2,*" %%a in (' robocopy "%%~fY." "%%~fY." file.txt /l /nocopy /is /s /nc /ns /ts /ndl /njh /njs ^| sort /r 2^>nul ^| cmd /q /v /c "(set /p .=&echo(!.!)" ') do copy "%%~fY\it0\summary.yml" "%%~dpc." 可替换参数中的值存储在变量中,只需使用可替换参数

未经测试,但或多或​​少

E:\Backups\code

%%X作为当前活动目录:

  • E:\Backups\code将枚举Hazard%%Y
  • 下的文件夹
  • E:\Backups\code\Hazard将枚举testn%%a
  • 下的文件夹
  • robocopy执行file.txt命令以找到包含最新sort /r文件的文件夹
  • cmd按降序排序文件列表,以便最新文件是列表中的第一个
  • for仅检索并输出第一行
  • 使用多个copy可替换参数中的所有可用信息,执行指示的{{1}}命令。