为什么使用-delete查找会删除/ save /目录中的文件,而未删除却无法找到它们?


20

我想删除当前目录树中的所有文件,除外save。我运行了以下命令:

 find . \( -name save -prune \) -o -type f -ls | grep /save/

它没有发现。但是当我运行以下命令时:

 find . \( -name save -prune \) -o -type f -delete

/ save /中的所有那些文件都消失了。我想念什么?


4
哎呀……今天我学到了一些东西(谢谢你)。而且,我建议mv save/ ../some/safer/location在这种“通用”删除命令之前使用一个简单的命令(...当然,在您发帖之前,我会做同样的检查并遇到同样的麻烦!)。现在,为文件位于^^上的文件系统找到一个不错的“取消删除”
Olivier Dulac

3
我的痛苦是您的预防。
奥修斯'16

1
1000谢谢你。代码(通常是?)以神秘的方式起作用……
Olivier Dulac


@lesmana我赞成您的回答。不幸的是,我的find版本没有给我这么好的警告:(
Otheus

Answers:


26

-delete表示-depth不适用于-prune-depth从叶子开始)。在GNU版本的手册中有一个警告(-delete是FreeBSD扩展,现在GNU find和其他一些实现也支持该扩展)。

info find --index-search=-delete

在命令行上使用“ -delete”操作会自动打开“ -depth”选项(* note find Expressions::)。如果您以前只是使用“ -print”进行测试,这可能会令人惊讶,因此通常最好记住明确使用“ -depth”。

info find --index-search=-prune

因为“ -delete”表示“ -depth”,所以将“ -prune”与“ -delete”结合使用可能会导致删除比预期数量更多的文件。

在这里,您可以选择使用rm以下任一方法:

find . -name save -prune -o -type f -exec rm -f {} +

(如果其中存在其他人可写的目录,则可能不安全,因为您可能会在运行该命令时通过用符号链接替换目录来删除当前目录树之外的文件)。

一个更安全的选择:

find . -name save -prune -o -type f -execdir rm -f -- {} \;

那没有上面提到的问题,但是意味着rm每个文件运行一个。在--对FreeBSD的实现,而不是GNU一个前缀的文件名与是必要的./

另外,如Costas所建议:

LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete

(但是仍然不必要地下降到save目录中)

LC_ALL=C那里*匹配任何字节序列(即使是在当前语言环境中不构成有效字符的字节)。请注意,这将影响错误消息的语言(英语而不是用户的语言)。


这里的安全问题是rm什么?
jrw32982在2013年

@ jrw32982,请参见链接编辑到GNU找到手册
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.