批处理如何避免相同的第二个 FOR 循环?

Batch How to avoid a same 2nd FOR loop?

我创建了一个批处理脚本来将一些子文件夹从路径 A 备份到路径 B (Z:\Folder1\… > U:\Backup\…)。

该脚本列出路径 A 内的子文件夹,并为每个子文件夹递增一个数字。 然后,我只需要输入我要备份的子文件夹的编号,xcopy 会完成剩下的工作。

问题是有时我在路径 A 中有数千个子文件夹,只有少数要备份(10 或 15 个)。

我想要的是,一旦我输入这些文件夹的数量,它将直接进入备份,而不必再次循环路径 A 内的所有子文件夹(这需要时间)。

这是我的批次:

@echo off

setlocal EnableDelayedExpansion

rem Script for backuping some subfolders from path A to path B

set BackupLocation=U:\Backup
set subfolder_no=1

FOR /F "delims=" %%a IN ('dir /b "Z:\Folder1\*"') DO ( 

    set subfolder=%%a

    if defined subfolder (
        echo !subfolder_no! !subfolder!
        set /a subfolder_no+=1
        
    )
    
)
    
set /a subfolder_no=%subfolder_no%-1
set /a index=0
set /a choice=-1

echo.
set /p choice=Enter the number(s) of the subfolder(s) you want to backup: 

FOR /F "delims=" %%a IN ('dir /b "Z:\Folder1\*"') DO ( 

    set subfolder=%%a

    if defined subfolder (
        set /a index+=1
    )

FOR %%f IN (%choice%) DO if %%f==!index! (

echo.
echo Backuping subfolder !subfolder!

xcopy "Z:\Folder1\!subfolder!" "%BackupLocation%\!subfolder!\" /e /i /y

)
)

echo.
pause

exit

我该怎么做?是否可以从匹配编号中获取子文件夹的名称并将它们存储在变量或其他东西中?

非常感谢您的帮助!

这是一个只枚举目录一次的例子。

请注意,虽然它在技术上回答了您的问题并执行了您要求的任务,但此版本旨在按预期在 Windows 10 上工作。您询问的特定部分在其他版本中也适用也一样,但是 :BackUp 标记的部分使用 sort 命令的新的和未记录的 Windows 10 功能,return 只有选择列表中的唯一项目。否则,您的最终用户可能会在技术上多次提供相同的数字,从而触发同一目录的多次备份。 由于这部分代码在技术上超出了您的问题范围,如果您要在较旧的操作系统上部署它,我将让您自己修改代码部分。

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Rem Script for backing up some subdirectories of a Source path to a Backup path.
Set "SourceLocation=Z:\Folder1"
Set "BackupLocation=U:\Backup"

If Not Exist "%Sourcelocation%\." Exit /B
If Not Exist "%Backuplocation%\." Exit /B

:ShowSet
For /F "Delims==" %%G In ('"(Set subdirectory[) 2>NUL"') Do Set "%%G="
Set "index=0"
For /F "EOL=? Delims=" %%G In ('Dir /B /A:D /O:N "%SourceLocation%" 2^>NUL'
) Do (Set /A index += 1
    Set "subdirectory=%%G"
    SetLocal EnableDelayedExpansion
    Echo !index! !subdirectory!
    For /F "Tokens=1,*" %%H In ("!index! !subdirectory!") Do (EndLocal
        Set "subdirectory[%%H]=%%I"))
If Not Defined subdirectory[1] Exit /B

:Select
Echo(
Echo Please type the number(s) for the subdirectories you want to backup,
Echo(
Echo For multiple selections please separate each with spaces e.g. 1 3 6
Echo For none please type 0 or press [ENTER].
Set "selection=0"
Set /P "selection=>"
Set "selection=%selection:"=%"
Set "selection=%selection:)=%"
If Not Defined selection GoTo Select
If "%selection%" == "0" GoTo :EOF
(Set selection) | "%SystemRoot%\System32\findstr.exe"^
 /X /R /C:"selection=[0123456789 ][0123456789 ]*" 1>NUL || GoTo Select
Set "selection=%selection% "

:BackUp
For /F %%G In (
    '"(Echo(%selection: =^&Echo(%) | "%SystemRoot%\System32\sort.exe" /Unique"'
) Do If Not Defined subdirectory[%%G] (Echo Selection %%G was not valid) Else (
    SetLocal EnableDelayedExpansion
    Echo(&Echo Backing up subdirectory %%G !subdirectory[%%G]!
    "%SystemRoot%\System32\Robocopy.exe" ^
     "%SourceLocation%\!subdirectory[%%G]!" ^
      "%BackupLocation%\!subdirectory[%%G]!" /E /NC /NDL /NJH /NJS /NS ^
       | %SystemRoot%\System32\find.exe /V " (0x00000005) "
    EndLocal)
Pause

:BackUp 部分,我使用了 Robocopy.exe 而不是您使用的已弃用的 xcopy.exe 实用程序.

如果您仍希望使用 xcopy.exe,请替换:

    "%SystemRoot%\System32\Robocopy.exe" ^
     "%SourceLocation%\!subdirectory[%%G]!" ^
      "%BackupLocation%\!subdirectory[%%G]!" /E /NC /NDL /NJH /NJS /NS ^
       | %SystemRoot%\System32\find.exe /V " (0x00000005) "

与:

    "%SystemRoot%\System32\xcopy.exe" ^
     "%SourceLocation%\!subdirectory[%%G]!" ^
      "%BackupLocation%\!subdirectory[%%G]!\" /E /I /Y