gpt4 book ai didi

batch-file - 批处理文件使用 7zip 提取嵌套的 zip 并在提取成功后删除 zip

转载 作者:行者123 更新时间:2023-12-04 09:21:44 25 4
gpt4 key购买 nike

我有一个装满 zip 文件的文件夹。这些 zip 文件有时包含 zip 文件,有时在其中包含 zip 文件,等等。我正在尝试编写一个批处理文件,我可以将其粘贴到包含所有 zip 的顶部文件夹中,当它运行时,它将解压缩所有嵌套的 zip 文件,并在子目录中,一直向下,并删除一次 zip它们已被成功提取。需要保留完整的文件路径。如果出现错误并且无法提取文件,则不应删除该文件,并且需要将文件和文件路径打印到文本文件中。
到目前为止,我有这个:

@ECHO ON

SET source=%cd%
FOR /F "TOKENS=*" %%F IN ('DIR /S /B "%source%\*.zip"') DO "C:\Program Files\7-Zip\7z.exe" x "%%~fF" -o"%%~pF\"
EXIT
我可以将其放入文件夹并运行,它将解压缩第一级 zip 文件,但不会解压缩其中的任何嵌套 zip 文件。这是第一个障碍。
下一个障碍是删除成功提取的 zip。最后,不要删除任何无法提取的 zip 文件并将其名称和/或路径打印到文本文件中。
任何建议或代码块表示赞赏。或者如果有更好的方法来完全做到这一点。
**** 更新 ****
Mofi 发布了一个答案,看起来它在工作,除了一个:
一个ZIP解压的时候,需要解压到同名文件夹,所以还是可以按照结构来的。
启动示例:
[Top Level Folder Holding Zips] (folder)
--ExampleZip.zip
---FileInZip.txt
---FileinZip2.txt
--ExampleZip2.zip
---Folder1 (folder)
----ExampleZip3.zip
-----FileinZip3.txt
-----FileinZip4.txt
---ExampleZip4.zip
----FileinZip5.txt
----FileinZip6.txt
需要变成这样:
[Top Level Folder Holding Zips] (folder)
--ExampleZip (folder)
---FileInZip.txt
---FileinZip2.txt
--ExampleZip2 (folder)
---Folder1 (folder)
----ExampleZip3 (folder)
-----FileinZip3.txt
-----FileinZip4.txt
---ExampleZip4 (folder)
----FileinZip5.txt
----FileinZip6.txt
所以完整的结构仍然可见。
我认为这个问题的最佳答案显示了我需要包括的内容: Extract zip contents into directory with same name as zip file, retain directory structure
这部分:

SET "filename=%~1"
SET dirName=%filename:~0,-4%

7z x -o"%dirName%" "%filename%"
需要在某处粉碎。或者似乎应该有一个 7Zip 的开关来执行此操作,因为您可以使用“提取到 *”从上下文菜单中执行此操作,我认为这就是“使用完整路径提取”命令的作用,但这必须有所作为使用 -o 开关,指定输出路径?如何将输出路径指定为与输入 zip 同名的文件夹?或者将我与 Mofi 的答案链接的那个问题的答案合并?
*** 再次更新 ***
我认为批处理文件存在一个问题,忽略名称中带有下划线的 ZIP 文件,但这是一个巧合,它实际上忽略了没有设置存档文件属性的 ZIP 文件。
Mofi 建议了另一种修复方法,但批处理文件没有提取需要存档文件属性集的嵌套 zip。
这确实有点工作,因为我可以手动执行批处理文件几次,它将通过文件夹中的所有内容工作,但循环计算似乎不起作用,或者在批处理文件设置之前计算/终止所有 zip 文件的存档属性?
这是我正在使用的当前版本:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ErrorOutput="
set "LoopCount=20"

rem The current directory is used on batch file being called without
rem a base folder path or with just one or more double quotes.
set "BaseFolder=%~1"
if defined BaseFolder set "BaseFolder=%BaseFolder:"=%"
if not defined BaseFolder set "BaseFolder=%CD%" & goto VerifyFolderPath

rem Make sure the folder path contains backslashes and not forward slashes
rem and does not contain wildcard characters or redirection operators or a
rem horizontal tab character after removing all double quotes.
set "BaseFolder=%BaseFolder:/=\%"
for /F "delims=*?|<> " %%I in ("%BaseFolder%") do if not "%BaseFolder%" == "%%I" (
echo ERROR: %~nx0 must be called with a valid folder path.
echo "%~1" is not a valid folder path.
set "ErrorOutput=1"
goto EndBatch
)

rem Get full folder path in case of the folder was specified with
rem a relative path. If the folder path references the root of a
rem drive like on using "C:\" or just "\", redefine the folder
rem path with full path for root of the (current) drive.
for %%I in ("%BaseFolder%") do set "BaseFolder=%%~fI"

:VerifyFolderPath
rem The base folder path must end with a backslash for verification.
if not "%BaseFolder:~-1%" == "\" set "BaseFolder=%BaseFolder%\"

rem Verify the existence of the folder. The code above processed also
rem folder paths of folders not existing at all and also invalid folder
rem paths containing for example a colon not (only) after drive letter.
if not exist "%BaseFolder%" (
echo ERROR: Folder "%BaseFolder%" does not exist.
set "ErrorOutput=1"
goto EndBatch
)

rem Make sure to process all ZIP files existing in base folder and all
rem its subfolders by setting archive file attribute on all ZIP files.
%SystemRoot%\System32\attrib.exe +A /S "%BaseFolder%*.zip"

rem Process all *.zip files found in base folder and all its subfolders
rem which have the archive file attribute set. *.zip files with archive
rem file attribute not set are ignored to avoid an endless running loop
rem if a ZIP archive file cannot be extracted successfully with reason(s)
rem output by 7-Zip or if the ZIP file cannot be deleted after successful
rem extraction of the archive. The archive extraction loop runs are limited
rem additionally by a loop counter as defined at top of the batch file for
rem 100% safety on prevention of an endless loop execution.

:ExtractArchives
set "ArchiveProcessed="
for /F "delims=" %%I in ('dir "%BaseFolder%*.zip" /AA-D /B /S 2^>nul') do (
set "ArchiveProcessed=1"
echo Extracting archive: "%%I"
"%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpnI\" -spd -y -- "%%I"
@pause
if errorlevel 255 set "ErrorOutput=1" & goto EndBatch
if errorlevel 1 (
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
) else (
del /A /F "%%I"
if exist "%%I" (
echo ERROR: Failed to delete: "%%I"
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
)
)
)
if not defined ArchiveProcessed goto EndBatch
set /A LoopCount-=1
if not LoopCount == 0 goto ExtractArchives

:EndBatch
if defined ErrorOutput echo/& pause
endlocal
echo[
echo[
echo If no errors are displayed above, everything extracted successfully. Remember to delete the batch file once you are done.
@pause
很少有可能有 10 或 20 层嵌套 zip,因此快速而肮脏的修复可能只是以某种方式循环整个批处理文件 10 或 20 次,除非这是一个坏主意或有更优雅的方法做吧。

最佳答案

通过循环运行 ZIP 存档文件提取过程直到不再存在 ZIP 文件,可以实现递归提取所有 ZIP 存档(包括 ZIP 存档内的嵌套 ZIP 存档)的任务。但是必须至少考虑两个用例,以避免无休止的运行归档提取循环:

  • 无论出于何种原因,ZIP 存档文件的提取都失败。 7-Zip 输出有关错误原因的信息。不应再次处理此类 ZIP 文件。
  • 无论出于何种原因,删除成功提取的 ZIP 文件都会失败。不应再次处理 ZIP 文件。

  • 解决方案是仅处理存档文件属性设置为 Windows 在创建、重命名或修改文件时自动完成的 ZIP 文件,并删除提取过程或文件删除未能避免处理的每个 ZIP 文件上的存档文件属性再次下载 ZIP 文件。
    存档文件属性设置在目录树上的所有 *.zip 文件上,以便在开始存档文件提取过程之前进行处理,以确保真正所有现有的 *.zip 文件至少被处理一次。存档文件属性也设置在一个完全成功处理的 ZIP 存档文件的输出目录中的所有 *.zip 文件上,以确保即使在解压后未设置存档文件属性的 ZIP 文件中的 *.zip 文件也将在下一步处理存档文件提取循环运行。
    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "ErrorOutput="
    set "LoopCount=20"

    rem The current directory is used on batch file being called without
    rem a base folder path or with just one or more double quotes.
    set "BaseFolder=%~1"
    if defined BaseFolder set "BaseFolder=%BaseFolder:"=%"
    if not defined BaseFolder set "BaseFolder=%CD%" & goto VerifyFolderPath

    rem Make sure the folder path contains backslashes and not forward slashes
    rem and does not contain wildcard characters or redirection operators or a
    rem horizontal tab character after removing all double quotes.
    set "BaseFolder=%BaseFolder:/=\%"
    for /F "delims=*?|<> " %%I in ("%BaseFolder%") do if not "%BaseFolder%" == "%%I" (
    echo ERROR: %~nx0 must be called with a valid folder path.
    echo "%~1" is not a valid folder path.
    set "ErrorOutput=1"
    goto EndBatch
    )

    rem Get full folder path in case of the folder was specified with
    rem a relative path. If the folder path references the root of a
    rem drive like on using "C:\" or just "\", redefine the folder
    rem path with full path for root of the (current) drive.
    for %%I in ("%BaseFolder%") do set "BaseFolder=%%~fI"

    :VerifyFolderPath
    rem The base folder path must end with a backslash for verification.
    if not "%BaseFolder:~-1%" == "\" set "BaseFolder=%BaseFolder%\"

    rem Verify the existence of the folder. The code above processed also
    rem folder paths of folders not existing at all and also invalid folder
    rem paths containing for example a colon not (only) after drive letter.
    if not exist "%BaseFolder%" (
    echo ERROR: Folder "%BaseFolder%" does not exist.
    set "ErrorOutput=1"
    goto EndBatch
    )

    rem Make sure to process all ZIP files existing in base folder and all
    rem its subfolders by setting archive file attribute on all ZIP files.
    %SystemRoot%\System32\attrib.exe +A /S "%BaseFolder%*.zip" >nul

    rem Process all *.zip files found in base folder and all its subfolders
    rem which have the archive file attribute set. *.zip files with archive
    rem file attribute not set are ignored to avoid an endless running loop
    rem if a ZIP archive file cannot be extracted successfully with reason(s)
    rem output by 7-Zip or if the ZIP file cannot be deleted after successful
    rem extraction of the archive. The archive extraction loop runs are limited
    rem additionally by a loop counter as defined at top of the batch file for
    rem 100% safety on prevention of an endless loop execution.

    :ExtractArchives
    set "ArchiveProcessed="
    for /F "delims=" %%I in ('dir "%BaseFolder%*.zip" /AA-D /B /S 2^>nul') do (
    set "ArchiveProcessed=1"
    echo Extracting archive: "%%I"
    "%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpI" -spd -y -- "%%I"
    if errorlevel 255 set "ErrorOutput=1" & goto EndBatch
    if errorlevel 1 (
    set "ErrorOutput=1"
    %SystemRoot%\System32\attrib.exe -A "%%I"
    ) else (
    %SystemRoot%\System32\attrib.exe +A /S "%%~dpnI\*.zip" >nul
    del /A /F "%%I"
    if exist "%%I" (
    echo ERROR: Failed to delete: "%%I"
    set "ErrorOutput=1"
    %SystemRoot%\System32\attrib.exe -A "%%I"
    )
    )
    )
    if not defined ArchiveProcessed goto EndBatch
    set /A LoopCount-=1
    if not LoopCount == 0 goto ExtractArchives

    :EndBatch
    if defined ErrorOutput echo/& pause
    endlocal
    注: "delims=*?|<> 后必须有一个水平制表符和 "在批处理文件代码的第 16 行,而不是从浏览器窗口复制代码并将代码粘贴到文本编辑器窗口后的一系列空格字符。
    批处理文件用带有命令 的行注释。 REM (评论)。应该阅读这些注释以理解代码,然后可以删除这些注释,以便 Windows 命令处理器更有效地执行批处理文件。
    7-Zip 代码中使用的开关由 的帮助解释7-Zip 通过双击文件打开 7-zip.chm或开通 帮助 从开始的 GUI 窗口中 7-Zip .在帮助选项卡 目录 展开列表项 命令行版本 然后点击列表项 开关 显示帮助页面 命令行开关 当前使用的 版本支持的所有开关7-Zip .
    可以使用文件夹路径作为参数执行批处理文件,以处理此文件夹及其所有子文件夹中的所有 ZIP 文件。所以可以添加到 发送至 的上下文菜单Windows 文件资源管理器 运行批处理文件的快捷方式文件,文件夹路径为 Windows 文件资源管理器 到批处理文件作为第一个参数。也可以将批处理文件注册为 Directory 的上下文菜单选项。在 Windows 注册表中,以便能够从任何支持目录的 Windows 上下文菜单处理程序的应用程序中轻松运行批处理文件。
    问题编辑后编辑:命令行运行 7-Zip 可以修改为:
    "%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpnI\" -spe -spd -y -- "%%I"
    由于替换 -o"%%~dpI",每个 ZIP 文件都使用此命令行解压缩到 ZIP 文件文件夹中的子文件夹中,该文件夹的名称为 ZIP 文件名。来自 -o"%%~dpnI\" .附加 7-Zip 开关 -spe如果 ZIP 文件在顶层包含与 ZIP 文件同名的文件夹,则避免复制文件夹名称。所以如果 Example3.zip包含顶级文件夹 Example3 , 文件被解压到文件夹 Example3而不是文件夹 Example3\Example3因为它会在不使用选项 -spe 的情况下发生.
    要了解使用的命令及其工作原理,请打开 command prompt窗口,在那里执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面。
  • attrib /?
  • call /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

  • 阅读有关 Using command redirection operators 的 Microsoft 文档 2>nul的解释.重定向操作符 >必须用插入字符转义 ^对于 当 Windows 命令解释器在执行命令之前处理此命令行时,将被解释为文字字符的命令行 对于 执行嵌入式 dir在后台启动的单独命令进程中的命令行。

    关于batch-file - 批处理文件使用 7zip 提取嵌套的 zip 并在提取成功后删除 zip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63095250/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com