【问题标题】:Recursively unzip files and then delete original file, leaving unzipped files in place from shell递归解压缩文件,然后删除原始文件,将解压缩文件从 shell 保留在适当位置
【发布时间】:2011-08-01 05:08:40
【问题描述】:

到目前为止,我已经弄清楚如何使用 find 递归解压缩所有文件:

find . -depth -name `*.zip` -exec /usr/bin/unzip -n {} \; 

但是,我不知道如何在提取后一次删除一个 zip 文件。在 -a -exec 中添加 rm *.zip 最终会在提取之前删除每个目录中的大部分 zip 文件。通过包含 rm 命令的脚本(启用 -i 以进行测试)导致 find 找不到任何 *.zips (或者至少这是它所抱怨的)。当然,许多文件名中都有空格,但此时在 sed 命令中添加 _'s 的语法有点超出我的能力。感谢您的帮助!

【问题讨论】:

  • 你是什么意思recursively,zip in zip?对于复杂的任务,我个人会编写一个帮助脚本(比如unzip-and-rm.sh)并 -exec 该脚本。
  • 如果我不够清楚,我深表歉意。目录树至少向下六或七级,而 zip 文件位于最深的级别。每个 zip 文件都包含另外两个文件,我希望保持其他文件不变,然后删除 zip 文件。我最初的尝试只是将unzip-and-rm 插入脚本并执行它,但它找不到任何 zip 文件,我怀疑这是由于文件名中的空格造成的。
  • 我不知道为什么it fails to find any zip files,我不敢相信,你能粘贴命令行吗?
  • 如果您想了解更多信息,请查看stackoverflow.com/a/51841035/2457251 的答案。例如,您可以将命令 rm $fmv $f 添加到 .sh 文件中 - 或添加任何其他命令,如果您愿意。

标签: bash unzip rm


【解决方案1】:

我有一个目录,里面装满了压缩的 csv 文件。外部进程经常向其写入新的压缩文件。我希望像您一样批量解压缩并删除原件。

为此,我使用:

    unzip '*.zip'
    find . | sed 's/$/\.zip/g' | xargs -n 1 rm 

它通过搜索和展开当前目录中的所有 zip 文件来工作。稍后,在它完成后,可能还会有新的解压缩新文件混入其中,但尚未删除。

所以我通过找到成功解压缩的 *.csv 文件来删除,并使用 sed 重新生成要删除的原始文件名,然后通过 xargs 命令将其馈送到 rm。

【讨论】:

    【解决方案2】:

    根据文件名(../file.zip -> ../file/..)解压缩子目录中的档案:

    for F in $(find . -depth -name *.zip); do unzip "$F" -d "${F%.*}/" && rm "$F"; done
    

    【讨论】:

      【解决方案3】:

      你试过了吗:

      find . -depth -name '*.zip' -exec /usr/bin/unzip -n {} \; -exec rm {} \;
      

      find . -depth -name '*.zip' -exec /usr/bin/unzip -n {} \; -delete
      

      或在解压后运行第二个查找

      find . -depth -name '*.zip' -exec rm {} \;   
      

      【讨论】:

      • 我收到了find: paths must precede expression: /usr/bin/unzip
      • 啊!第二个选项效果很好。 -delete,我怎么不认识你!我当然忘记提及的主要标准之一是解压缩和删除应该背靠背进行,因为驱动器不够大,无法解压缩所有内容然后返回删除。非常感谢!
      • 警告:当 zip 文件是其他 zip 文件时,第三个选项不起作用。
      • -1 警告此命令会将所有 zip 解压缩到您的工作目录中。如果将拉链留在找到它们的路径中会更好。
      • 请注意,如果您有多个(i)name 子句,则这些子句必须用括号括起来:find \( -iname "*.zip" -o -iname "*.7z" \) -execdir 7z x {} \; -delete
      【解决方案4】:

      如上所述,这应该可行。

      找到 . -depth -name '*.zip' -execdir unzip -n {} \; -删除

      但是,请注意两点:

      • -n 选项指示解压缩不覆盖现有文件。您可能不知道 zip 文件是否与名称相似的目标文件不同。即使这样,-delete 也会删除 zip 文件。
      • 如果 unzip 无法解压缩文件(例如由于错误),它可能仍会删除它。如果使用 -exec rm {} \; 代替 -delete,该命令肯定会删除它。

      更安全的解决方案可能是将解压缩后的文件移动到单独的目录中,当您确定已成功解压缩所有文件时,您可以将其丢弃。

      【讨论】:

        【解决方案5】:

        感谢第二个带有 -delete 的命令!帮了我很多.. 我这边只有 2 条(也许有帮助)评论:

        -必须在我的 debian 系统上使用 '.zip' 而不是 `.zip`

        -使用 -execdir 而不是 -exec > 这将在其当前文件夹中提取每个 zip 文件,否则您最终会在您调用的目录中获得所有提取的内容查找 cmd。

        找到 . -depth -name '*.zip' -execdir /usr/bin/unzip -n {} \; -删除

        THX 和问候, 北方

        【讨论】:

        • 您可以添加一条附加说明,即如果您有多个 (i)name 子句,则必须将它们括在括号中:find \( -iname "*.zip" -o -iname "*.7z" \) -execdir 7z x {} \; -delete。另请注意,iname 可能更好,因为它也匹配 .ZIP
        猜你喜欢
        • 2011-02-17
        • 1970-01-01
        • 2016-05-02
        • 1970-01-01
        • 1970-01-01
        • 2019-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多