我有一个文件夹,其中有许多子文件夹,其中包含小的 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
^^^^^^^^^^^
此测试根据大小过滤文件。这是与此问题相关的部分。
注意-
前面的160k
。160k
意味着正好是 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 不要查看超过一级的深度。实际上它不会进入子目录。