如何删除所有子文件夹中小于特定大小的所有文件?

如何删除所有子文件夹中小于特定大小的所有文件?

我有一个文件夹,其中有许多子文件夹,其中包含小的 tif 文件(小于 160kb),这些文件已合并到更大的 pdf 文件中,以及一些大的多页 tif 文件。

我想删除所有小的 tif 文件而不删除较大的文件(tif 或 pdf)并保留目录结构。如何在 Linux 上使用命令行进行此操作?

答案1

find . -type f -name "*.tif" -size -160k -delete

这将递归地(在当前目录和所有子目录中)搜索文件名与 glob 匹配*.tif且大小小于 160 千字节的文件,然后删除它们。

先运行命令-delete。它只会列出文件而不是删除文件。这样您就可以验证要删除的文件是否正确。


解释:

典型的 find 命令如下所示

find dirname -test a -test b -action

我们从中的所有文件(和所有目录)开始dirname。然后测试根据某些标准过滤文件(和目录)。测试按顺序进行。因此第二个测试从第一个测试中获取结果。然后操作根据最终结果执行操作。如果没有给出明确的操作,那么它是默认的-print(打印文件名包括文件路径)。

在我们的案例中:

find . -type f -name "*.tif" -size -160k -delete

我们从当前目录开始(点:).;过滤目录(-type f);按名称过滤;按大小过滤;最终删除这些文件。

现在解释每个部分。为了简洁起见,从现在开始我将只说“文件”而不是“文件和目录”。


find . -type f -name "*.tif" -size -160k -delete
                                         ^^^^^^^

这是操作。顾名思义,它指示 find 删除找到的文件。

目录只有为空时才会被删除。在我们的例子中,这并不重要,因为我们过滤掉了目录。

其他常见操作包括-printf(根据自定义格式打印)或-exec(对找到的文件执行命令)。还有-ls将以类似于命令的格式打印找到的文件ls

如上所述:如果你省略该操作,则默认操作是-print


find . -type f -name "*.tif" -size -160k -delete
                             ^^^^^^^^^^^

此测试根据大小过滤文件。这是与此问题相关的部分。

注意-前面的160k160k意味着正好是 160 千字节。-160k意味着小于 160 千字节。+160k意味着大于 160 千字节。

如果您想要小于并等于 160k 那么请这样做-161k

如果您想要以字节为单位过滤大小(例如 160 字节而不是 160 千字节),那么您必须像这样编写:160c。如果您直接编写,160它将被解释为 160*512 字节。这是 POSIX 的一个奇怪要求。请阅读此处了解更多详细信息:https://unix.stackexchange.com/questions/259208/purpose-of-find-commands-default-size-unit-512-bytes


find . -type f -name "*.tif" -size -160k -delete
               ^^^^^^^^^^^^^

此测试根据文件名过滤文件。

该模式是一个 glob。它的工作方式与你在典型命令中预期的一样,例如rm *.tif

请小心将 glob 放在引号 ( "*.tif") 中。否则,shell 会在 find 获取参数之前扩展 glob,并执行完全不同的命令。有关引用 glob 的更多信息,请参阅此处:https://unix.stackexchange.com/questions/82139/what-is-the-difference-between-pl-and-pl-in-grep-why-does-quoting-change

有几种测试可以根据文件的“名称”进行过滤:-name无论文件的路径如何,都与文件名匹配。-path与文件名匹配文件的路径。并且-regex使用正则表达式而不是 glob 来匹配包括路径在内的文件名。

有关 glob 和 regex 的更多信息请阅读本文https://www.linuxjournal.com/content/globbing-and-regex-so-similar-so-different或者搜索“difference glob regex”


find . -type f -name "*.tif" -size -160k -delete
       ^^^^^^^

此测试根据类型进行过滤。在本例中,我们要求它仅过滤文件。

如果你忽略这个测试,你将得到文件和目录。

通常您只想过滤文件或目录,因为许多过滤器和操作仅对文件或目录有意义。

要仅过滤目录,请使用-type d


find . -type f -name "*.tif" -size -160k -delete
     ^

点 ( .) 代表当前目录。您还可以在当前目录中搜索另一个目录

find some/dir -type f -name "*.tif" -size -160k -delete

或系统某处的绝对路径

find /absolute/path -type f -name "*.tif" -size -160k -delete

在合理版本的 find(GNU find)中,您可以省略点,它将默认在当前目录中搜索。几乎所有的 Linux 都使用 GNU 版本的 find。一些价格过高的非自由系统(Mac OS X)使用过时和/或劣质版本的 find,只是为了避免 GPL(GNU 和 Linux 的永久自由许可证)。

有关苹果避免使用 GPL 的更多信息请参见此处:http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/


奖金!

如果你想排除子文件夹,或者换句话说:不递归,那么这样做

find . -maxdepth 1 -type f -name "*.tif" -size -160k -delete
       ^^^^^^^^^^^

这将告诉 find 不要查看超过一级的深度。实际上它不会进入子目录。

相关内容