【问题标题】:Recursively unzip all subdirectories while retaining file structure递归解压所有子目录,同时保留文件结构
【发布时间】:2021-12-29 12:03:53
【问题描述】:

我是 bash 脚本的新手,我发现很难解决这个问题。

我有一个父文件夹,其中包含子目录和压缩子目录的混合。

在这些子目录中还有更多嵌套的 zip 文件。

不仅有 .zip 文件,还有 .rar 和 .7z 文件,其中还包含嵌套的 zips/rars/7zs。

我想递归地解压缩、解压缩和解压缩所有嵌套的子目录,直到父文件夹不再包含任何 .rar、.zip、.7zip 文件。 (这些最终需要在提取后删除)。可能有数千个子目录都在不同的嵌套深度。你可以有压缩文件夹或压缩文件。

但是我想保留我的文件夹结构,所以解压后的文件夹必须保留在解压后的位置

我试过这个解压脚本,但它不保留文件结构。

#!/bin/bash

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]

do
    find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done

                             

我想要例如:

文件夹“a”包含压缩文件夹“b.zip”,其中包含压缩文本文件 pear.zip(即已压缩到 pear.zip a/b.zip(/pear.zip) 的 pear.txt)

我希望文件夹 'a' 包含 'b' 以包含 pear.txt 'a/b/pear.txt'

上面的脚本将“b”(b 为空)和梨都放入文件夹“a”中,在该文件夹中执行脚本,这不是我想要的。例如'a/b'和'a/pear.txt'

【问题讨论】:

  • 当您解压缩一个 zip 文件时,它将重新创建目录(以及其中的文件),就像它们存储在所述 zip 中一样。我不确定我是否理解你的问题,似乎你想要 zip 无论如何......?
  • 所以路径是:b/pear.zip,那么b/被压缩成b.zip?这是有问题的。拉链是否只有一层?还是更多?
  • @Nic3500 是的,我认为你是对的。无论如何,我确实想要 zip 做的事情,但递归地并且对 unrar 和 unzip 也做同样的事情。之前,我指的是具体的示例脚本是如何输出的,而不是那样做。 - 为混乱道歉。
  • @Nic3500 你的脚本的问题是unzip 的工作目录永远不会改变。一切都提取到.。您需要为每个不同的目录指定unzip -d dir(或更改工作目录)。
  • @dan 有两个级别的压缩。 (b) 是一个包含压缩文本文件的压缩目录。 'a' 包含 b.zip,其中包含 pear.zip。 b.zip 提取后给出 (b),其中包含 pear.zip (b/pear.zip),当 pear.zip 被提取时,它变为 pear.txt。两次解压过程,产生a/b/pear.txt。 (a 是父级,开始时没有压缩)。它可能是更多压缩文件夹的嵌套。这只是我能想到的最简单的例子。

标签: linux bash recursion command-line zip


【解决方案1】:

你可以试试这个:

#!/bin/bash

while :; do
    mapfile -td '' archives \
    < <(find . -type f -name '*.zip' -o -name '*.7z' -print0)

    [[ ${#archives[@]} -eq 0 ]] && break

    for i in "${archives[@]}"; do
        case $i in
            *.zip) unzip -d "$(dirname "$i")" -- "$i";;
            *.7z)  7z x "-o$(dirname "$i")" -- "$i";;
        esac
    done

    rm -rf "${archives[@]}" || break
done
  • 每个档案都由find 列出。该列表被提取到正确的位置,并且档案被删除。如此重复,直到找到零个档案。

  • 您可以添加一个等效的unrar 命令(我不熟悉它)。

  • -o -name '*.rar' 添加到find,并将另一个案例添加到case。如果没有使用unrar 指定目标目录的选项,您可以使用cd "$(dirname "$i")" &amp;&amp; unrar "$i"

  • 此脚本存在一些问题。特别是,如果提取失败,存档仍会被删除。否则会导致无限循环。如果提取失败,您可以使用unzip ... || exit 1 退出,并手动处理。

  • 通过计算未删除但希望没有必要的文件,既可以避免删除,也可以避免无限循环。

  • 我无法正确测试这个。 YMMV。

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2013-03-16
    相关资源
    最近更新 更多