【问题标题】:Batch file script to zip files用于压缩文件的批处理文件脚本
【发布时间】:2013-12-27 10:27:25
【问题描述】:

我在这种模式中有一个文件夹结构。我刚刚展示了两个子目录和每个子目录中的 2 个文件,但通常我在一个级别上有 n 个子目录,在它们下面有一个级别的文件(但可以是 n 个文件)。

Directory master
subDirectory x:
  file1
  file2
Directory y:
  file 3
  file 4

我需要创建一个 Windows 脚本,一个从主目录运行的批处理文件,并给我两个包含它们各自文件的 zip 文件 x.zip 和 y.zip。

我知道我的脚本必须使用 for 和 zip 命令,但我正在努力让它工作,因为我无法从这些命令的语法中理解,而且谷歌搜索似乎没有帮助。

我找到了类似 for %f in ("*.*") do zip "%~nf.zip" "%f" 的命令,但它似乎只有在文件直接存在且没有子文件夹的情况下才有效。

【问题讨论】:

标签: windows batch-file


【解决方案1】:

启动 windows 10 build 17063,您可以使用 TAR。 MSDN link

例如,要为内部文件夹 Reports 中名为文件夹 XYZ 的目录创建一个 zip 文件,您可以在命令提示符中输入以下内容。

tar -cf XYZ.zip \Reports\XYZ

【讨论】:

    【解决方案2】:

    简单的脚本 它将桌面中的所有转储文件夹和子文件夹文件转换为 backup.zip

    在backup.bat中写下这一行并执行

    "C:\Program Files\7-Zip\7z.exe" a -tzip "C:\Users\shris\Desktop\backup.zip" -r "C:\Users\shris\Desktop\dump\*" -mx5
    

    【讨论】:

      【解决方案3】:

      我喜欢PodTech.io 的回答,无需其他工具即可实现这一目标。对我来说,它并没有开箱即用,所以我不得不稍微改变它。我不确定是否需要原始脚本中的命令wScript.Sleep 12000(12 秒延迟),所以我保留了它。

      这是根据他的回答修改后的脚本Zip.cmd,对我来说效果很好:

      @echo off   
      if "%1"=="" goto end
      
      setlocal
      set TEMPDIR=%TEMP%\ZIP
      set FILETOZIP=%1
      set OUTPUTZIP=%2.zip
      if "%2"=="" set OUTPUTZIP=%1.zip
      
      :: preparing VBS script
      echo Set objArgs = WScript.Arguments > _zipIt.vbs
      echo InputFolder = objArgs(0) >> _zipIt.vbs
      echo ZipFile = objArgs(1) >> _zipIt.vbs
      echo Set fso = WScript.CreateObject("Scripting.FileSystemObject") >> _zipIt.vbs
      echo Set objZipFile = fso.CreateTextFile(ZipFile, True) >> _zipIt.vbs
      echo objZipFile.Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
      echo objZipFile.Close >> _zipIt.vbs
      echo Set objShell = WScript.CreateObject("Shell.Application") >> _zipIt.vbs
      echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
      echo Set objZip = objShell.NameSpace(fso.GetAbsolutePathName(ZipFile)) >> _zipIt.vbs
      echo if not (objZip is nothing) then  >> _zipIt.vbs
      echo    objZip.CopyHere(source) >> _zipIt.vbs
      echo    wScript.Sleep 12000 >> _zipIt.vbs
      echo end if >> _zipIt.vbs
      
      @ECHO Zipping, please wait...
      mkdir %TEMPDIR%
      xcopy /y /s %FILETOZIP% %TEMPDIR%
      WScript _zipIt.vbs  %TEMPDIR%  %OUTPUTZIP%
      del _zipIt.vbs
      rmdir /s /q  %TEMPDIR%
      
      @ECHO ZIP Completed.
      :end
      

      用法:

      • 一个参数(此处不允许使用通配符):

        Zip FileToZip.txt

        将在包含压缩文件FileToZip.txt 的同一文件夹中创建FileToZip.txt.zip

      • 两个参数(第一个参数可以使用通配符),例如

        压缩 *.cmd 脚本

        在包含所有匹配的*.cmd 文件的同一文件夹中创建Scripts.zip


      注意:如果要调试VBS脚本, check out this hint,它描述了如何激活调试器来逐步完成。

      【讨论】:

        【解决方案4】:

        这是归档个人的正确语法;批量文件夹作为单独的压缩文件...

        for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\*"
        

        【讨论】:

          【解决方案5】:

          这是Tomaslink 有一个编写良好的脚本来压缩文件夹的内容。

          要使其正常工作,只需将脚本复制到批处理文件中,然后通过指定要压缩的文件夹(源)来执行它。

          不需要提及目标目录,因为它在脚本中默认为桌面(“%USERPROFILE%\Desktop”)

          在此处复制脚本,以防万一网络链接已关闭:

          @ECHO OFF
          SETLOCAL ENABLEDELAYEDEXPANSION
          
          SET sourceDirPath=%1
          IF [%2] EQU [] (
            SET destinationDirPath="%USERPROFILE%\Desktop"
          ) ELSE (
            SET destinationDirPath="%2"
          )
          IF [%3] EQU [] (
            SET destinationFileName="%~n1%.zip"
          ) ELSE (
            SET destinationFileName="%3"
          )
          SET tempFilePath=%TEMP%\FilesToZip.txt
          TYPE NUL > %tempFilePath%
          
          FOR /F "DELIMS=*" %%i IN ('DIR /B /S /A-D "%sourceDirPath%"') DO (
            SET filePath=%%i
            SET dirPath=%%~dpi
            SET dirPath=!dirPath:~0,-1!
            SET dirPath=!dirPath:%sourceDirPath%=!
            SET dirPath=!dirPath:%sourceDirPath%=!
            ECHO .SET DestinationDir=!dirPath! >> %tempFilePath%
            ECHO "!filePath!" >> %tempFilePath%
          )
          
          MAKECAB /D MaxDiskSize=0 /D CompressionType=MSZIP /D Cabinet=ON /D Compress=ON /D UniqueFiles=OFF /D DiskDirectoryTemplate=%destinationDirPath% /D CabinetNameTemplate=%destinationFileName%  /F %tempFilePath% > NUL 2>&1
          
          DEL setup.inf > NUL 2>&1
          DEL setup.rpt > NUL 2>&1
          DEL %tempFilePath% > NUL 2>&1
          

          【讨论】:

          • @ChamindaBandara,不是您面临的问题。我在 Windows 10 上测试过这段代码。
          • 我在一个文件夹中运行了脚本,但什么都不会发生。
          • 它有点工作(在 Windows 10 上),但将存档作为“.zip”放在您的桌面上,没有名称。内置的 ZIP 不理解该文件,但您可以使用 7zip 解析生成的文件。所以它“有点”工作。可能只需要一些逻辑上的改进,实际上它只是使用了 MAKECAB 功能,我认为这很聪明。无论如何,最好。
          【解决方案6】:

          对 7zip 或 ZIP 没有外部依赖 - 创建一个 vbs 脚本并执行:

              @ECHO Zipping
              mkdir %TEMPDIR%
              xcopy /y /s %FILETOZIP% %TEMPDIR%
              echo Set objArgs = WScript.Arguments > _zipIt.vbs
              echo InputFolder = objArgs(0) >> _zipIt.vbs
              echo ZipFile = objArgs(1) >> _zipIt.vbs
              echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
              echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
              echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
              echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
              @ECHO *******************************************
              @ECHO Zipping, please wait..
              echo wScript.Sleep 12000 >> _zipIt.vbs
              CScript  _zipIt.vbs  %TEMPDIR%  %OUTPUTZIP%
              del _zipIt.vbs
              rmdir /s /q  %TEMPDIR%
          
              @ECHO *******************************************
              @ECHO      ZIP Completed
          

          【讨论】:

          • 你知道这是否适用于 Windows XP 机器?
          • 您刚刚创建了对 VBScript 的依赖项。如果您要这样做,请使用未过时的依赖项,例如 Powershell: >>> Compress-Archive -Path -DestinationPath .zip
          • 我必须进行一些修改才能让它在我的终端上运行(Windows 10)。 Here's 我改变了什么。
          【解决方案7】:

          我知道为时已晚,但如果你还想尝试

          for /d %%X in (*) do (for /d %%a in (%%X) do ( "C:\Program Files\7-Zip\7z.exe" a -tzip "%%X.zip" ".\%%a\" ))
          

          这里 * 是当前文件夹。更多选项请尝试this link

          【讨论】:

          • 答案中的链接已失效。
          • 链接不再可用。如果我理解正确的用法,对于 .GZ 存档,您应该在命令中使用 -tgz 和 filename.gz,对吗?
          【解决方案8】:

          你就在附近:)

          首先,批处理 (%%variable) 和 Windows CMD (%variable) 使用不同的变量命名。 其次,我不知道你如何使用 CMD 中的 zip。我认为这是来自 Linux 用户。在 Win 上使用内置的 zip 操作并不容易,使用批处理脚本更难。

          不过你还是很幸运的。我从 cygwin 包中得到(解压到目标文件夹)zip.exe 和 cygwin1.dll(文件大小均为 3mb),现在就开始使用它。

          当然,我使用 CMD 进行更好/更快的测试,而不是批处理。只记得在怪我之前将 %varname 修改为 %%varname :P

          for /d %d in (*) do zip -r %d %d

          说明: for /d ... 匹配里面的任何文件夹。只有文件夹忽略文件。 (用于 /f 来匹配文件) for /d %d in ... %d 告诉 cmd 你想将哪个名称分配给你的变量。我把 d 用来匹配 widh d (目录含义)。 for /d %d in (*) ... 非常重要。这假设我 CD 到所需的文件夹,或从中运行。 (*) 这意味着所有在这个目录上,因为我们使用/d 文件没有被处理,所以不需要设置模式,即使如果你需要,你只能得到一些文件夹。您可以使用绝对路径。不确定批次中亲属的问题。 for /d %d in (*) do zip -r ... 做 ZIP 很明显。 (执行 zip 本身并查看帮助显示以使用您的自定义规则)。 r- 用于递归,因此将添加任何内容。 for /d %d in (*) do zip -r %d %d 第一个 %d 是 zip 名称。您可以尝试使用 myzip.zip,但如果您有 2 个或更多文件夹,则第二个文件夹无法给出第一个文件夹的名称,并且不会在没有更多参数的情况下尝试覆盖。因此,我们将 %d 传递给两者,这是当前用于迭代的文件夹名称,该文件夹名称被压缩到具有该文件夹名称的文件中。不必将“.zip”附加到名称中。

          开始玩时比我预期的要短。

          【讨论】:

          • 你不应该使用-rp吗?否则重复的文件名会冲突,不是吗?
          • 正如你所说,当尝试添加相同的文件名时会发生冲突,但是......我们从真实文件夹中获取真实文件。没有任何重复的文件名。我们将每个子文件夹的内容放入一个命名为文件夹的 zip 中。没有碰撞。开始发布时,我尝试将真实文件夹放入我的系统:)
          • 感谢大家的回复,并感谢 erm3nda 的详细解释。这一切都帮助了我。再次感谢。
          【解决方案9】:
          for /d %%a in (*) do (ECHO zip -r -p "%%~na.zip" ".\%%a\*")
          

          应该在一个批次中工作。

          请注意,我添加了一个ECHO 来简单地显示建议的命令。您需要删除 ECHO 关键字才能执行命令。

          【讨论】:

          • 您是否在包含 ECHO 行之前或之后尝试过?
          • 两种方式。你发现问题了吗?
          • 是的,但可能是因为我使用了 cygwin 的 zip.exe。我第一次在现场直播时在 mi Win7 cmd 上输入 zip ……但什么也没做……所以我得到了 cygwin 的。使用@monacraft 我得到 a.zip 与 $a etcetc 没有比较。我不知道 ~n... 我不需要它来执行相同的操作。使用您的脚本,我知道 *\ 是 dos 样式,建议使用 posix /*/ 以及关于 varname 和文件名之间比较的相同问题。如果您有兴趣,我可以发布完整的错误消息。
          • 明确的问题是:您可以从头开始使用 cmd 中的 zip 吗?
          • 可能,不。它不是内置命令或提供的实用程序。从我安装 Free Pascal 开始,我的路径上有一份 Info-ZIP zip.exe 的副本。如果您使用的是Winzip,那么您需要命令行支持实用程序WZZIP.exe。在此代码中将wzzip 替换为zip 会产生类似的结果,但压缩效果更好。如果您使用的是其他实用程序,那么 - YMMV。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-19
          • 1970-01-01
          相关资源
          最近更新 更多