【问题标题】:How to remove the content of folders before unzipping many zips? (bash script)如何在解压缩多个 zip 之前删除文件夹的内容? (bash 脚本)
【发布时间】:2021-12-26 12:27:24
【问题描述】:

我在 FTP 上有许多文件夹及其内容,其中一些我必须不时更新。我通过解压缩收到的 zip 文件来更新它们。 zip 的名称可能多种多样,但在 zip 中,总有一个主文件夹与应在 FTP 上更新的文件夹的名称完全相同。除了包含其内容的主文件夹之外,zip 中没有其他文件/文件夹。所以我在下面写了一个简单的脚本来更新它们:

unzip -o \*.zip
rm -f *.zip

问题是,有时这些文件夹中的一些文件应该被删除 - 它们不再存在于带有更新的 zip 中。而且我意识到,当我解压缩并覆盖时,什么都不会被删除。是否可以修改此脚本,以确保在解压缩之前删除整个文件夹?要更新的文件夹的正确名称不是 zip 的名称,而是 zip 中主文件夹的名称,因此我不知道如何解决这个问题。我找不到现有的解决方案。另外,有时我一次上传许多 zip,而 FTP 上有数千个文件夹,因此很难为每个文件夹编写一个命令。

【问题讨论】:

  • 为什么要提到 FTP。 FTP 是否在您的问题中发挥了作用,或者如果您从其他来源接收 zip 档案,它会是同样的问题吗?

标签: bash zip unzip


【解决方案1】:

您可以使用unzip 配套程序zipinfo 列出压缩文件的内容。添加模式*/ 以仅列出目录。然后通过管道发送到xargs 以删除它们。

zipinfo -1 '*.zip' '*/' | xargs rm -rf 2>/dev/null

这将立即删除所有现有目录(在现有 zip 文件中匹配)。然后,您可以运行脚本的其余部分来提取新的。

您可以在xargs 之前添加cut -d / -f 1 | sort -u | 以过滤掉rm 的任何子目录,但即使有也无所谓。

xargs 按空格分割行,因此包含空格的目录名称可能会导致删除不同的目录。对于 GNU xargs,您可以添加 --delimiter='\n' 来阻止它(还有 --null,但 zip 无论如何都会截断文件名中的新行)。您也可以通过grep -v '[[:space:]]' 管道排除包含空格的目录。

另一种可能有用的方法是一次处理一个 zip 文件:

for zip in *.zip; do
    dirs=$(zipinfo -1 "$zip" '*/') || continue
    IFS=$'\n' read -rd '' -a dirs<<<"$dirs"

    rm -rf "${dirs[@]}"
    unzip -o "$zip"
done

此方法也适用于空格。将dirs 拆分为一个数组仅意味着rm 在存档中有多个目录时仍然会成功。如果zipinfo 失败,则可能意味着存档已损坏或无法读取,因此|| continue。如果您想尝试提取,则可以将其删除。

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多