如何从Unix命令行递归地解压缩目录及其子目录中的存档?

chu*_*tor 58 unix recursion spaces unzip

unzip命令没有递归解压缩存档的选项.

如果我有以下目录结构和存档:

/Mother/Loving.zip
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes.zip

我想将所有档案解压缩到与每个档案同名的目录中:

/Mother/Loving/1.txt
/Mother/Loving.zip
/Scurvy/Sea Dogs/2.txt
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes/3.txt
/Scurvy/Cures/Limes.zip

我会发出什么命令或命令?

重要的是,这不会阻塞其中包含空格的文件名.

小智 95

如果要将文件解压缩到相应的文件夹,可以尝试这样做

find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;
Run Code Online (Sandbox Code Playgroud)

适用于可处理高I/O的系统的多处理版本:

find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"'
Run Code Online (Sandbox Code Playgroud)

  • 我不知道 xargs 有多核支持! (4认同)
  • __NOTE__ - 这不会根据请求将文件提取到与存档同名的目录中. (3认同)
  • 出于某种原因,第一个例子对我来说和 emlai 有同样的问题,所有解压缩的文件都放在 zip 文件所在的目录中。 然而,第二个,多线程方法,不仅工作得更快,而且把每个 zip以 zip 文件命名的目录中的文件。完美的! (3认同)
  • 这是正确的方法,因为它保留了完整的目录结构! (2认同)

chu*_*tor 34

这是一个涉及find命令和while循环的解决方案:

find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;
Run Code Online (Sandbox Code Playgroud)

  • **注意** - 当您请求相对解压缩时,将所有zip文件解压缩到**工作目录!**.见[Vivek的回答](http://stackoverflow.com/a/2318189/3191896) (5认同)

rob*_*nst 16

一个正确处理所有文件名(包括换行符)并提取到与文件位于同一位置的目录的解决方案,只需删除扩展名:

find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
Run Code Online (Sandbox Code Playgroud)

请注意,您可以.jar通过添加它们来轻松地使其处理更多文件类型(例如)-o,例如:

find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ...
Run Code Online (Sandbox Code Playgroud)

  • 建议更改为“find . -iname...”以解压缩 .ZIP 和 .zip 文件 (2认同)

Jah*_*gir 6

您可以在一个命令行中使用find和-exec标志来完成这项工作

find . -name "*.zip" -exec unzip {} \;
Run Code Online (Sandbox Code Playgroud)

  • 这会将所有内容解压缩到当前目录中,而不是相对于每个子目录。它也不会解压缩到与每个存档同名的目录中。 (2认同)

Pra*_*hav 5

这完全符合我们的要求:

解压文件:

find . -name "*.zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'
Run Code Online (Sandbox Code Playgroud)

上述命令不会创建重复的目录。

删除所有 zip 文件:

find . -depth -name '*.zip' -exec rm {} \;
Run Code Online (Sandbox Code Playgroud)