简体   繁体   English

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

[英]Renaming and moving files while in a loop in a batch script

So I want to be able to drag one or more rar or zip files to a batch.cmd script that extracts the file with 7zip to a directory one level up, renames the extracted file to the current folder name and then deletes the folder with the rar or zip archives.所以我希望能够将一个或多个 rar 或 zip 文件拖到一个 batch.cmd 脚本中,该脚本使用 7zip 将文件提取到上一级目录,将提取的文件重命名为当前文件夹名称,然后删除文件夹rar 或 zip 档案。

So far I have:到目前为止我有:

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

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

rmdir "%work%"

And that extracts the file to the current directory and renames it to the archive name but I want to name it to the directory the archive is in so %%~nA needs to be changed but typing "for /?"然后将文件提取到当前目录并将其重命名为存档名称,但我想将其命名为存档所在的目录,因此需要更改 %%~nA 但键入“for /?” doesn't seem to give me an option to get the current directory.似乎没有给我一个获取当前目录的选项。 Then I need to move the extracted file one level up and delete the folder with the archive files, I just don't know how to reference the files when using move and rmdir when in a loop.然后我需要将提取的文件向上移动一级并删除包含存档文件的文件夹,我只是不知道如何在循环中使用 move 和 rmdir 时引用文件。

This is my first attempt at batch scripting please go easy on me.这是我第一次尝试批处理脚本,请 go 对我放轻松。

This is going to be more of a lesson on how to do reasonably good programing in *cough* a bad *cough* the batch programming language.这将更多地是关于如何在*咳*糟糕的*咳*批处理编程语言中进行相当好的编程的课程。

The first stage is to work from the outside inwards, or top down.第一阶段是由外而内,或自上而下的工作。 It only took a few minutes to build this framework.构建这个框架只花了几分钟。 The sub goals/steps are:子目标/步骤是:

  1. Simply loop through all of the parameters and see if we can save them to a variable and then echo them out.只需循环遍历所有参数,看看我们是否可以将它们保存到一个变量中,然后将它们回显出来。
  2. Figure out how to extract the SubFolderName (This will later be the file name), and echo it per each loop.弄清楚如何提取 SubFolderName(稍后将成为文件名),并在每个循环中回显它。
  3. Build the Extract folder and echo per each loop.构建 Extract 文件夹并在每个循环中回显。
  4. Realize you forgot you were going to need the folder path of the calling batch file, add it as first parameter, and extract it before entering the:ltpLoop.意识到您忘记了您将需要调用批处理文件的文件夹路径,将其添加为第一个参数,并在进入:ltpLoop 之前将其解压缩。

The %1 gets the first parameter, while SHIFT will shift all parameters so that %1=%2, %2=%3, %3=%4, %4=%5, etc... This effectively removes the first parameter and reduces the total number of parameters by 1. The IF statement exits the script when SHIFT has removed all parameters and %1 no longer has a value. %1 获取第一个参数,而 SHIFT 将移动所有参数,以便 %1=%2、%2=%3、%3=%4、%4=%5 等...这有效地删除了第一个参数并将参数总数减 1。当 SHIFT 删除所有参数并且 %1 不再具有值时,IF 语句退出脚本。

Also, a lot of people will follow the ECHO command with a period (ECHO.Text to echo), but I had one bad case where period printed a blank line instead of the text, but semicolon;此外,很多人会在 ECHO 命令后加上一个句号(ECHO.Text to echo),但我有一个糟糕的情况,句号打印了一个空行而不是文本,而是分号; was fine - so I no do period, period!很好-所以我不做期间,期间!

@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

In stage 2 we start by cleaning up the code by removing the unneeded echos.在第 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

Start experimenting in the <<New Code Will Go Here>> area.在 <<New Code Will Go Here>> 区域开始试验。

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

The code is tested by creating 5 folders, with one zip file in each folder, and dragging the folders on to the batch file and seeing if we like the commands it built.通过创建 5 个文件夹来测试代码,每个文件夹中有一个 zip 文件,并将文件夹拖到批处理文件中,看看我们是否喜欢它构建的命令。

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

Then we try to build the extraction commands:然后我们尝试构建提取命令:

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

Check if results look correct:检查结果是否正确:

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

In stage 3 we try it for real - remove the echo:在第 3 阶段,我们进行真正的尝试——移除回声:

"%ProgramFiles%\7-Zip\7z.exe" e -o"%ExtractFolder%" "%%~C"

Check if we like the results (You can see I'm using some old latitude-e5440 PDFs I happen to find in a forgotten folder someplace):检查我们是否喜欢结果(您可以看到我正在使用一些我碰巧在某个被遗忘的文件夹中找到的旧 latitude-e5440 PDF):

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

For stage 4 we echo both the extract command and xcopy command to see what they look like:对于第 4 阶段,我们回显 extract 命令和 xcopy 命令以查看它们的外观:

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

Just a reminder, every test is done by dragging the 5 folders onto the batch file:提醒一下,每次测试都是通过将 5 个文件夹拖到批处理文件中来完成的:

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

Stage 5, try it live:第 5 阶段,现场试用:

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

What did we get?:我们得到了什么?:

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

Stage 6, what will remove directory look like?阶段 6,删除目录会是什么样子? (Decided to hide the other commands with REM) (决定用 REM 隐藏其他命令)

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

And we have:我们有:

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

Stage 7 is the final code and tests:阶段 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%\7-Zip\7z.exe" e -o"%ExtractFolder%" "%%~C"
        XCOPY /V /C /Y "%ExtractFolder%\*.*" "%CmdPath%\%SubFolderName%.*"
        RD /Q /S "%Folder%"
    )

    SHIFT
    GOTO :ltpLoop

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

All folders were deleted when done.完成后所有文件夹都被删除。

Now, let's do something experimental.现在,让我们做一些实验。 I've never seen this fail, but I haven't used it that often.我从来没有见过这个失败,但我没有经常使用它。 Let's give it a try:试一试吧:

@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%\7-Zip\7z.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" %*

If any of the commands separated by && fail, then execution jumps to the command prefixed by ||.如果由 && 分隔的任何命令失败,则执行跳转到以 || 为前缀的命令。 But if all of the commands separated by && succeed without throwing an error code, then the command prefixed by ||但是,如果所有由 && 分隔的命令都成功且没有抛出错误代码,则以 || 为前缀的命令is skipped.被跳过。 In theory, this will prevent the folder from being deleted, and pause the code, if there is problem.理论上,这将防止文件夹被删除,并在出现问题时暂停代码。

So, we re-created the folders, and then used HxD to the damage zip file in volume4 folder.因此,我们重新创建了文件夹,然后使用HxD 修复了volume4 文件夹中损坏的zip 文件。 HxD 使 PDF 变坏

It worked perfectly.它工作得很好。 Folder volume4 was not deleted, Tried the test again, this time damaging the PDF in folder volume2, worked perfectly!文件夹volume4没有被删除,再次测试,这次破坏了文件夹volume2中的PDF,完美!

As you can tell, I can do things in Batch that many can't do in PowerShell, and yes @Olaf, that's not necessarily something to be proud of;如您所知,我可以在 Batch 中做许多在 PowerShell 中做不到的事情,是的@Olaf,这不一定值得骄傲; ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM