85

unzip命令没有递归解压缩档案的选项。

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

/母亲/爱.zip
/坏血病/Sea Dogs.zip
/坏血病/治愈/酸橙.zip

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

/母亲/爱/1.txt
/母亲/爱.zip
/坏血病/海狗/2.txt
/坏血病/Sea Dogs.zip
/坏血病/治愈/酸橙/3.txt
/坏血病/治愈/酸橙.zip

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

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

4

10 回答 10

150

如果您想将文件提取到相应的文件夹中,您可以试试这个

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"'
于 2010-02-23T12:50:56.547 回答
40

这是一种将所有 zip 文件提取到工作目录并涉及 find 命令和 while 循环的解决方案:

find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;
于 2008-09-20T12:08:31.507 回答
38

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

find . -iname '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'

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

find . '(' -iname '*.zip' -o -iname '*.jar' ')' -exec ...
于 2014-03-13T16:02:40.187 回答
5

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

find . -name "*.zip" -exec unzip {} \;
于 2008-09-20T12:20:06.690 回答
4

这可以按照我们的意愿完美运行:

解压文件:

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

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

删除所有 zip 文件:

find . -depth -name '*.zip' -exec rm {} \;
于 2018-03-29T10:47:18.297 回答
3

使用 -r 标志的类似 gunzip 的东西?...

递归遍历目录结构。如果命令行上指定的任何文件名是目录,gzip 将进入该目录并压缩它在其中找到的所有文件(或者在 gunzip 的情况下解压缩它们)。

http://www.computerhope.com/unix/gzip.htm

于 2008-09-20T12:11:06.070 回答
1

如果您使用的是 cygwin,则 basename 命令的语法略有不同。

find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;
于 2009-04-10T23:41:38.497 回答
1

我意识到这已经很老了,但是当我在寻找类似问题的解决方案时,它是谷歌的第一批热门产品之一,所以我会在这里发布我所做的。我的场景略有不同,因为我基本上只是想完全炸开一个罐子,以及其中包含的所有罐子,所以我编写了以下 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>如果您将其存储在一个文件中,而不是像我碰巧那样为非交互式外壳读取的文件中,则需要哪个。如果您将函数存储在加载在非交互式外壳上的文件中(例如,.bashrc我相信),您可以删除整个source语句。希望这会对某人有所帮助。

一点警告 -explodeFile也会删除压缩文件,您当然可以通过注释掉最后一行来更改它。

于 2013-05-14T10:06:13.603 回答
0

另一个有趣的解决方案是:

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;
于 2014-05-28T19:22:04.390 回答
-2

这对我有用

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)
于 2021-06-26T00:59:52.967 回答