如何从Unix命令行recursion地解压目录及其子目录中的归档文件?
unzip
命令没有用于recursion解压缩存档的选项。
如果我有以下目录结构和档案:
/Mother/Loving.zip /坏血病/海狗.zip /Scurvy/Cures/Limes.zip
我想把所有的档案解压到与每个档案同名的目录中:
/Mother/Loving/1.txt /Mother/Loving.zip /坏血病/海狗/ 2.txt /坏血病/海狗.zip /Scurvy/Cures/Limes/3.txt /Scurvy/Cures/Limes.zip
我会发出什么命令或命令?
重要的是,这不会窒息其中有空格的文件名。
如果你想提取文件到相应的文件夹,你可以试试这个
find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;
可处理高I / O的系统的多处理版本:
find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"'
以下是一个涉及find命令和while循环的解决scheme:
find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;
一个正确处理所有文件名(包括换行符)并解压缩到与文件位于同一位置的目录的解决scheme,只是删除了扩展名:
find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
请注意,通过使用-o
添加它们,您可以轻松地处理更多文件types(如.jar
),例如:
find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ...
您可以在一个命令行中使用find和-exec标志来完成这项工作
find . -name "*.zip" -exec unzip {} \;
像使用-r标志的gunzip?
recursion地旅行目录结构。 如果命令行中指定的任何文件名都是目录,则gzip将下降到目录中并压缩它在其中find的所有文件(或在gunzip中解压缩它们)。
如果您使用的是cygwin,则basename命令的语法略有不同。
find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;
我意识到这是非常古老的,但是当我在寻找类似的解决scheme时,它是Google上的第一个点击,所以我会发布我在这里做的。 我的情况稍有不同,因为我基本上只是想完全炸开一个jar子,以及其中包含的所有jar子,所以我写了下面的bash函数:
function explode { local target="$1" echo "Exploding $target." if [ -f "$target" ] ; then explodeFile "$target" elif [ -d "$target" ] ; then while [ "$(find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)")" != "" ] ; do find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)" -exec bash -c 'source "<file-where-this-function-is-stored>" ; explode "{}"' \; done else echo "Could not find $target." fi } function explodeFile { local target="$1" echo "Exploding file $target." mv "$target" "$target.tmp" unzip -q "$target.tmp" -d "$target" rm "$target.tmp" }
注意<file-where-this-function-is-stored>
,如果你正在将它存储在一个文件中,而这个文件并不是为非交互式shell读取的,就像我碰巧那样。 如果您将函数存储在加载在非交互式shell上的文件中(例如,我相信.bashrc
),则可以删除整个source
语句。 希望这会帮助某人。
有一点警告 – explodeFile
也会删除ziped文件,你当然可以通过注释掉最后一行来改变它。
另一个有趣的解决scheme是:
DESTINY=[Give the output that you intend] # Don't forget to change from .ZIP to .zip. # In my case the files were in .ZIP. # The echo were for debug purpose. find . -name "*.ZIP" | while read filename; do ADDRESS=$filename #echo "Address: $ADDRESS" BASENAME=`basename $filename .ZIP` #echo "Basename: $BASENAME" unzip -d "$DESTINY$BASENAME" "$ADDRESS"; done;