找到“-exec rm {} \;”与“-删除”

找到“-exec rm {} \;”与“-删除”

我试图理解这两个命令之间的区别:

find / -name .DS_Store -delete

find / -name ".DS_Store" -exec rm {} \;

我注意到该-exec ... {}方法是首选。为什么?哪一种更安全/更快/更好?我在我的上都用过MacBook一切似乎都运转良好。

答案1

-delete会表现得更好,因为它不必为每个匹配的文件生成一个外部进程,但是确保调用此选项过滤条件(即-name-cmin-type等),否则将删除指定的整个文件树。事实上,引用联机find帮助页:

GNU find 根据优先级规则(参见运算符部分),通过从左到右计算给定的表达式来搜索以每个给定起点为根的目录树,直到知道结果

例如,

find . -name .DS_Store -type f -delete

应该没事。

您可能会看到-exec rm {} +经常推荐,因为-delete并不存在于 的所有版本中find。我现在无法检查,但我很确定我曾经使用过find没有它的 。

两种方法都应该是“安全的”。

避免为每个匹配文件生成外部进程的开销的常用方法是:

find / -name .DS_Store -print0 | xargs -0 rm

(但请注意,这里也存在可移植性问题:并非所有版本的 find 都有-print0!)

答案2

假设.DS_Store代表文件而不是目录,最可移植且仍然快速的方法是:

sudo find / -name .DS_Store -exec rm {} +

唯一的风险是sudo无法使用,但现在风险很低。

-delete选项用于要求 FreeBSD 或更高版本的 GNU 查找,并且在其他一些find实现中仍然是非标准的,因此并不总是可用。

命令终止+不是通过不对文件系统上的每个存在运行命令\;来高度优化子句。它更普遍,由 POSIX 指定。execrm.DS_Store

答案3

对于像 MacBook 这样的机器,您不会发现这两个命令之间的性能差异太大。但是,如果您查看版本,-exec您会发现细微的差别:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

这意味着您将找到所有名为 的文件.file-to-delete。然而,此搜索可能会返回一些不需要的误报。和你一起做某事的时候sudo应该更加小心一点。使用的优点-exec rm {}是您可以rm像这样传递参数:

sudo find / -iname "*~"  -exec rm -i {} \;

在这个例子中,我想删除那些备份文件emacs。然而,该波浪号可能位于一些我不知道但可能很重要的模糊文件中。另外我想确认删除。所以我把这个选项放在命令-irm。这将为我提供交互式删除。

rm您还可以优化删除目录和文件的用法:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

简而言之,这-exec使您可以更好地控制删除找到的项目的实际命令。优点是您可以使用一种工具来查找文件,使用另一种工具来删除它们。此外,并非每个版本的查找实用程序都有该-delete选项。因此,最好将每种工具用于其正确的工作。这就是unix哲学——一种工具,一项工作,将它们一起使用来完成你需要做的事情。

答案4

除了现有答案之外,请注意,-delete如果目录不为空,则不会删除目录。所以-exec rm -r在这些情况下你需要。

例如,这不起作用:

$ find . -type d -name ".TemporaryItems" -delete
find: cannot delete ‘./.TemporaryItems’: Directory not empty

所以你需要这个:

find . -type d -name ".TemporaryItems" -exec rm -rv "{}" +

该示例将-v(--verbose) 选项添加到 rm。

相关内容