unzip
命令没有递归解压缩档案的选项。
如果我有以下目录结构和档案:
/母亲/爱.zip /坏血病/海狗.zip /坏血病/治愈/Limes.zip
我想将所有档案解压到与每个档案同名的目录中:
/母亲/爱/1.txt /母亲/爱.zip /坏血病/海狗/2.txt /坏血病/海狗.zip /坏血病/治愈/酸橙/3.txt /坏血病/治愈/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 . -iname '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
请注意,您可以通过使用
.jar
添加更多文件类型(例如 -o
),例如:
find . '(' -iname '*.zip' -o -iname '*.jar' ')' -exec ...
这是一种将所有 zip 文件提取到工作目录并涉及 find 命令和 while 循环的解决方案:
find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;
您可以在单个命令行中使用 find 和 -exec 标志来完成这项工作
find . -name "*.zip" -exec unzip {} \;
这完全符合我们的要求:
解压文件:
find . -name "*.zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'
以上命令不会创建重复的目录。
删除所有 zip 文件:
find . -depth -name '*.zip' -exec rm {} \;
类似使用 -r 标志的gunzip 之类的东西?....
递归遍历目录结构。如果命令行上指定的任何文件名是目录,gzip 将下降到该目录并压缩它在其中找到的所有文件(或者在gunzip 的情况下解压缩它们)。
如果您使用 cygwin,basename 命令的语法略有不同。
find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;
我意识到这已经很老了,但当我在寻找类似问题的解决方案时,它是 Google 上的第一批点击之一,所以我将在这里发布我所做的事情。我的场景略有不同,因为我基本上只是想完全爆炸一个罐子,以及其中包含的所有罐子,所以我编写了以下 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"
}
请注意,如果您将其存储在一个文件中,而该文件不是像我一样为非交互式 shell 读取的,则需要使用
<file-where-this-function-is-stored>
。如果您将函数存储在非交互式 shell 上加载的文件中(例如,我相信 .bashrc
),您可以删除整个 source
语句。希望这会对某人有所帮助。
一个小警告 -
explodeFile
还会删除压缩文件,您当然可以通过注释掉最后一行来更改它。
另一个有趣的解决方案是:
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;
您还可以循环遍历每个 zip 文件,创建每个文件夹并解压缩该 zip 文件。
for zipfile in *.zip; do
mkdir "${zipfile%.*}"
unzip "$zipfile" -d "${zipfile%.*}"
done
这对我有用
def unzip(zip_file, path_to_extract):
"""
Decompress zip archives recursively
Args:
zip_file: name of zip archive
path_to_extract: folder where the files will be extracted
"""
try:
if is_zipfile(zip_file):
parent_file = ZipFile(zip_file)
parent_file.extractall(path_to_extract)
for file_inside in parent_file.namelist():
if is_zipfile(os.path.join(os.getcwd(),file_inside)):
unzip(file_inside,path_to_extract)
os.remove(f"{zip_file}")
except Exception as e:
print(e)