我想要找到所有大于 100 MB 且超过 20 天的文件,并且只想单独压缩它们的 .TXT 和 .txt 文件

我想要找到所有大于 100 MB 且超过 20 天的文件,并且只想单独压缩它们的 .TXT 和 .txt 文件

我在用着

find $HOME  -type f -size +100M -mtime +20 -exec zip -m '{}.zip' '{}' \;

该命令正在压缩所有文件。我只想压缩 *.TXT 和 *.txt 文件。知道我们该怎么做吗?

答案1

请注意,-size +100M如果M后缀是非标准扩展名,则选择大小严格大于 100MiB(104,857,600 字节)的文件,而不是 100MB(100,000,000 字节)。对于(严格)大于 100MB 的大小,您需要-size +100000000c(这是标准的)。

-mtime +20适用于确切 21 天(或find调用时的纳秒)或更早的文件。您需要-mtime +19超过 20 天的文件(至少在符合 POSIX 的find实现中,并非所有都在这方面)。

假设您处于类似于 Bourne 的 shell 中,而不是zsh,则不加$HOME引号是没有意义的,因为在这里调用 split+glob 是没有意义的。在 POSIX shell 中,您还可以使用~代替"$HOME".

zip是一个不太 Unixy 命令。默认情况下,它会自行扩展通配符,因此如果您有一个名为 的文件*.txt,实际上会创建一个包含该目录中zip -m '*.txt.zip' '*.txt'所有文件的 zip 文件。txt如果该文件位于名为 example 的目录中,情况可能会变得更糟*。您可以使用该-nw标志来避免这种情况,或者使用支持旧 zip 格式(例如 .zip)的更unixy命令bsdtar

如果这样做find ~,则传递给的所有路径都zip将是绝对路径,因此最终,您将获得其成员及其完整路径 ( home/you/dir/file.txt...) 列出的 zip 文件。您可以使用 BSD/GNU-execdir find谓词或-j选项来zip避免这种情况。

请注意,并非所有find实现都会扩展{}in {}.zip,也就是说,when{}不是单独存在于 的参数中-exec。在那些没有的情况下,您需要使用 进行sh呼叫-exec sh -c 'zip -nw -m "$1.zip" -- "$1"' sh {} ';'

要匹配文件名,可以使用-name谓词。您可以使用'(' -name '*.txt' -o -name '*.TXT' ')'来匹配txtTXT文件,或者-name '*.[tT][xX][tT]'在某些find实现中-iname '*.txt'还包括Txt, tXT... 文件。对于多种find实现,-name要求文件名是用户区域设置中的有效文本。由于所有.txtTXT字符都是可移植字符集的一部分,因此您可以将区域设置修复为 C,以保证它始终匹配以这些字符结尾的文件,即使文件路径的其余部分在用户区域设置中不是有效文本。

所以:

LC_ALL=C find ~ '(' -name '*.txt' -o -name '*.TXT' ')' \
                -type f \
                -size +100000000c \
                -mtime +19 \
                -execdir zip -nw -m '{}.zip' -- '{}' ';'

或者使用zsh和:

for f (~/**/*.(txt|TXT)(ND.L+100000000m+19)) zip -j -nw -m $f.zip $f

请注意,zip 是 80 年代末的一种旧格式,按照今天的标准来看压缩率很低。它唯一的优点是它是 Microsoft 操作系统上唯一支持开箱即用的压缩格式(实际上,它既进行归档又进行压缩,而您在这里只需要后者)。

在这里,如果您不需要与 Microsoft 操作系统的互操作性,您可以使用更现代的压缩器,例如xzbzip2。即使gzip 从 90 年代初开始,它也使用相同的压缩算法,因为zip它只负责压缩,所以也可以更好地减小大小。所有这些还可以一次压缩多个文件,因此可以使压缩许多文件的过程更加高效,因为您可以更少地调用压缩器。

例如,你可以这样做:

xz ~/**/*.(txt|TXT)(ND.L+100000000m+19)

zshshell 一次调用即可更好地压缩所有这些文件xz


^这里是 86400 (24 × 60 × 60) Unix 秒,不是日历日,因为不考虑夏令时导致的时钟变化。

相关内容