在批处理脚本中循环重命名和移动文件

Renaming and moving files while in a loop in a batch script

所以我希望能够将一个或多个 rar 或 zip 文件拖到批处理 .cmd 脚本中,该脚本使用 7zip 将文件提取到上一级目录,将提取的文件重命名为当前文件夹名称,然后删除包含 rar 或 zip 存档的文件夹。

到目前为止我有:

set work=%temp%\%random%%random%%random%%random%
mkdir "%work%" || goto :eof

for %%A in (*.zip *.rar) do (
    "%ProgramFiles%-Zipz.exe" e -o"%work%" "%%~A"
    for %%F in ("%work%\*") do move "%%~F" "%%~nA%%~xF"
)

rmdir "%work%"

然后将文件提取到当前目录并将其重命名为存档名称,但我想将其命名为存档所在的目录,因此 %%~nA 需要更改但键入“for /?”似乎没有给我一个获取当前目录的选项。然后我需要将提取的文件向上移动一级并删除包含存档文件的文件夹,我只是不知道如何在循环中使用 move 和 rmdir 时引用文件。

这是我第一次尝试批处理脚本,请放轻松。

这将更多地是关于如何在 *咳* 糟糕 *咳* 批处理编程语言中进行相当好的编程的课程。

第一阶段是从外到内,或自上而下。构建这个框架只花了几分钟。子 goals/steps 是:

  1. 简单地遍历所有参数,看看我们是否可以将它们保存到一个变量中,然后将它们回显出来。
  2. 弄清楚如何提取 SubFolderName(稍后将成为文件名),并在每个循环中回显它。
  3. 构建 Extract 文件夹并在每个循环中回显。
  4. 意识到您忘记了您将需要调用批处理文件的文件夹路径,将其添加为第一个参数,并在进入 :ltpLoop 之前将其解压缩。

%1 获取第一个参数,而 SHIFT 将移动所有参数,以便 %1=%2、%2=%3、%3=%4、%4=%5 等...这有效删除第一个参数并将参数总数减少 1。当 SHIFT 删除所有参数并且 %1 不再具有值时,IF 语句退出脚本。

此外,很多人会在 ECHO 命令后加上一个句号(ECHO.Text 以回显),但我有一个糟糕的情况,句号打印了一个空行而不是文本,而是分号;很好-所以我不做句号,句号!

@ECHO OFF
    GOTO :Start

:LoopThroughParameters
    SET CmdPath=%~1
    SHIFT
    ECHO;[[[%CmdPath%]]]
:ltpLoop
    IF [%1] EQU [] GOTO :EOF
    SET Folder=%~1
    SET SubFolderName=%~nx1
    SET ExtractFolder=%~1\Extract

    ECHO;
    ECHO;[%Folder%]
    ECHO;[%SubFolderName%]
    ECHO;[%ExtractFolder%]
    SHIFT
    GOTO :ltpLoop

:Start
    CALL :LoopThroughParameters "%~dp0" %*
PAUSE

在第 2 阶段,我们首先通过删除不需要的回声来清理代码。

:LoopThroughParameters
    SET CmdPath=%~1
    SHIFT

:ltpLoop
    IF [%1] EQU [] GOTO :EOF
    SET Folder=%~1
    SET SubFolderName=%~nx1
    SET ExtractFolder=%~1\Extract
    <<New Code Will Go Here>>
    SHIFT
    GOTO :ltpLoop

在 <> 区域开始试验。

    ECHO;FOR %%C IN ("%Folder%\*.zip" "%Folder%\*.rar") DO (

代码通过创建 5 个文件夹进行测试,每个文件夹中有一个 zip 文件,然后将文件夹拖到批处理文件中,看看我们是否喜欢它构建的命令。

FOR %C IN ("D:\Temp\Whosebug345433\volume5\*.zip" "D:\Temp\Whosebug345433\volume5\*.rar") DO (
FOR %C IN ("D:\Temp\Whosebug345433\volume1\*.zip" "D:\Temp\Whosebug345433\volume1\*.rar") DO (
FOR %C IN ("D:\Temp\Whosebug345433\volume2\*.zip" "D:\Temp\Whosebug345433\volume2\*.rar") DO (
FOR %C IN ("D:\Temp\Whosebug345433\volume3\*.zip" "D:\Temp\Whosebug345433\volume3\*.rar") DO (
FOR %C IN ("D:\Temp\Whosebug345433\volume4\*.zip" "D:\Temp\Whosebug345433\volume4\*.rar") DO (

然后我们尝试构建提取命令:

    FOR %%C IN ("%Folder%\*.zip" "%Folder%\*.rar") DO (
        ECHO;"%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"
    )

检查结果是否正确:

"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume5\Extract" "D:\Temp\Whosebug345433\volume5\Last Zip file.zip"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume1\Extract" "D:\Temp\Whosebug345433\volume1\SomeZipFile.zip"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume2\Extract" "D:\Temp\Whosebug345433\volume2\JustAnotherZip.zip"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume3\Extract" "D:\Temp\Whosebug345433\volume3\YetAnotherZip.zip"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume4\Extract" "D:\Temp\Whosebug345433\volume4\How Many Zips Was This.zip"

在第 3 阶段,我们进行真正的尝试 - 删除回声:

"%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"

检查我们是否喜欢结果(您可以看到我正在使用一些旧的 latitude-e5440 PDF,我碰巧在某个被遗忘的文件夹中找到):

D:\Temp\Whosebug345433>dir /s /b
D:\Temp\Whosebug345433\DragDropAndExtract.CMD
D:\Temp\Whosebug345433\volume1
D:\Temp\Whosebug345433\volume2
D:\Temp\Whosebug345433\volume3
D:\Temp\Whosebug345433\volume4
D:\Temp\Whosebug345433\volume5
D:\Temp\Whosebug345433\volume1\Extract
D:\Temp\Whosebug345433\volume1\SomeZipFile.zip
D:\Temp\Whosebug345433\volume1\Extract\lat_e_reimage_guide_en-us.pdf
D:\Temp\Whosebug345433\volume2\Extract
D:\Temp\Whosebug345433\volume2\JustAnotherZip.zip
D:\Temp\Whosebug345433\volume2\Extract\latitude-e5440-laptop_owners-manual_en-us.pdf
D:\Temp\Whosebug345433\volume3\Extract
D:\Temp\Whosebug345433\volume3\YetAnotherZip.zip
D:\Temp\Whosebug345433\volume3\Extract\latitude-e5440-laptop_user's guide_en-us.pdf
D:\Temp\Whosebug345433\volume4\Extract
D:\Temp\Whosebug345433\volume4\How Many Zips Was This.zip
D:\Temp\Whosebug345433\volume4\Extract\latitude-e5440-laptop_users-guide_en-us.pdf
D:\Temp\Whosebug345433\volume5\Extract
D:\Temp\Whosebug345433\volume5\Last Zip file.zip
D:\Temp\Whosebug345433\volume5\Extract\latitude-e5440-laptop_white papers_en-us.pdf

对于第 4 阶段,我们回显 extract 命令和 xcopy 命令以查看它们的外观:

        ECHO;"%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"
        ECHO; XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"

提醒一下,每次测试都是通过将 5 个文件夹拖到批处理文件中来完成的:

"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume5\Extract" "D:\Temp\Whosebug345433\volume5\Last Zip file.zip"
XCOPY /V /C /Y "D:\Temp\Whosebug345433\volume5\Extract\*.*" "D:\Temp\Whosebug345433\volume5.*"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume1\Extract" "D:\Temp\Whosebug345433\volume1\SomeZipFile.zip"
XCOPY /V /C /Y "D:\Temp\Whosebug345433\volume1\Extract\*.*" "D:\Temp\Whosebug345433\volume1.*"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume2\Extract" "D:\Temp\Whosebug345433\volume2\JustAnotherZip.zip"
XCOPY /V /C /Y "D:\Temp\Whosebug345433\volume2\Extract\*.*" "D:\Temp\Whosebug345433\volume2.*"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume3\Extract" "D:\Temp\Whosebug345433\volume3\YetAnotherZip.zip"
XCOPY /V /C /Y "D:\Temp\Whosebug345433\volume3\Extract\*.*" "D:\Temp\Whosebug345433\volume3.*"
"C:\Program Files-Zipz.exe" e -o"D:\Temp\Whosebug345433\volume4\Extract" "D:\Temp\Whosebug345433\volume4\How Many Zips Was This.zip"
XCOPY /V /C /Y "D:\Temp\Whosebug345433\volume4\Extract\*.*" "D:\Temp\Whosebug345433\volume4.*"

第 5 阶段,现场试玩:

        "%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"
        XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"

我们得到了什么?:

D:\Temp\Whosebug345433>dir /s/b
D:\Temp\Whosebug345433\volume1
D:\Temp\Whosebug345433\volume1.pdf
D:\Temp\Whosebug345433\volume2
D:\Temp\Whosebug345433\volume2.pdf
D:\Temp\Whosebug345433\volume3
D:\Temp\Whosebug345433\volume3.pdf
D:\Temp\Whosebug345433\volume4
D:\Temp\Whosebug345433\volume4.pdf
D:\Temp\Whosebug345433\volume5
D:\Temp\Whosebug345433\volume5.pdf

第 6 阶段,删除目录会是什么样子? (决定用REM隐藏其他命令)

        REM "%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"
        REM XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"
        ECHO;RD /Q /S "%Folder%"

我们有:

RD /Q /S "D:\Temp\Whosebug345433\volume5"
RD /Q /S "D:\Temp\Whosebug345433\volume1"
RD /Q /S "D:\Temp\Whosebug345433\volume2"
RD /Q /S "D:\Temp\Whosebug345433\volume3"
RD /Q /S "D:\Temp\Whosebug345433\volume4"

第 7 阶段是最终代码和测试:

@ECHO OFF
    GOTO :Start

:LoopThroughParameters
    SET CmdPath=%~1
    SHIFT

:ltpLoop
    IF [%1] EQU [] GOTO :EOF
    SET Folder=%~1
    SET SubFolderName=%~nx1
    SET ExtractFolder=%~1\Extract
    
    FOR %%C IN ("%Folder%\*.zip" "%Folder%\*.rar") DO (
        "%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C"
        XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"
        RD /Q /S "%Folder%"
    )

    SHIFT
    GOTO :ltpLoop

:Start
    CALL :LoopThroughParameters "%~dp0" %*
PAUSE

完成后删除了所有文件夹。

现在,让我们做一些实验。我从来没有见过这个失败,但我没有经常使用它。让我们试一试:

@ECHO OFF
    GOTO :Start

:LoopThroughParameters
    SET CmdPath=%~1
    SHIFT

:ltpLoop
    IF [%1] EQU [] GOTO :EOF
    SET Folder=%~1
    SET SubFolderName=%~nx1
    SET ExtractFolder=%~1\Extract
    
    FOR %%C IN ("%Folder%\*.zip" "%Folder%\*.rar") DO (
        ( 
            "%ProgramFiles%-Zipz.exe" e -o"%ExtractFolder%" "%%~C" 
        ) && (
            XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"
        ) && (
            RD /Q /S "%Folder%"
        ) || (
            PowerShell Write-Host -ForegroundColor red "Error:"
            PAUSE
        )
    )

    SHIFT
    GOTO :ltpLoop

:Start
    CALL :LoopThroughParameters "%~dp0" %*

如果以&&分隔的任何命令失败,则执行跳转到以||为前缀的命令。但是,如果所有由 && 分隔的命令都成功且没有抛出错误代码,则以 || 为前缀的命令被跳过。理论上,这将防止文件夹被删除,并暂停代码,如果有问题。

所以,我们re-created文件夹,然后使用HxD对volume4文件夹中的损坏zip文件。

效果很好!文件夹 volume4 未删除。再次尝试测试,这次损坏了文件夹volume2中的PDF,完美运行!

如您所知,我可以在 Batch 中做许多在 PowerShell 中做不到的事情,是的@Olaf,这不一定值得骄傲! ;)