find . -name ".svn"
这给了我以下结果:
./toto/.svn
./toto/titi/.svn
./toto/tata/.svn
如何使用
rm -fr
处理所有这些行以删除目录及其内容?#1 楼
Find可以为找到的每个匹配项使用-exec
选项执行参数。这是推荐的机制,因为您可以正确处理带有空格/换行符和其他字符的路径。您必须先删除目录的内容,然后才能删除目录本身,因此请使用带有-r
命令的rm
来实现此目的。对于您的示例,您可以发出:
find . -name ".svn" -exec rm -r "{}" \;
您还可以通过添加
-type d
检查来告诉find只是找到名为.svn的目录:find . -name ".svn" -type d -exec rm -r "{}" \;
警告将
rm -r
与警告,它会删除该文件夹及其所有内容。如果要删除仅空目录以及仅包含空目录的目录,请使用
-delete
和-empty
自己进行删除:find . -name ".svn" -type d -empty -delete
评论
我已经看到了在find命令中始终在-name之后运行-type的建议,因为调用stat来获取类型很昂贵。我只是自己在相当大的文件上尝试过,这似乎是对的:运行find。 -name'foo'-type d花了19秒,而find。 -type d -name'foo'用了32秒。因此,先运行-type的时间延长约50%。
–旋转
2015年3月16日16:37
我已经使用此命令多年,但是现在在Mac上,我收到错误消息,指出这些目录不存在。即使确实删除了它们。我以前从没看过消息。
–碎肉
15/12/23在8:51
与@chovy相同。有办法摆脱这些消息吗?
–Clément
16年4月23日在15:32
@chovy @clément这是因为find希望在该文件夹中查看其他匹配项,同时它正在删除该文件夹。 〜我还不知道该如何解决。〜肮脏的解决方法:查找。名称“删除文件夹” -print0 | xargs -r0-rm -r
–查理
16 Jul 20'12:02
@chovy @Clément我认为-depth参数可以解决此问题:find。 -depth -name“ .svn” -type d -exec rm -r“ {}” \;
–金博兰
16 Jul 27'7:57
#2 楼
这是一种比接受的答案方式还快的便携式方法。使用
+
代替分号,因为find
命令终止符可以优化CPU使用率。如果您有很多.svn
子目录,那么这可能很重要:find . -name .svn -type d -exec rm -rf {} +
请注意,您永远不需要在这里引用花括号。
1除非您使用
fish
shell(自从我写完此回复以来,这个问题可能已经解决了)。评论
+和分号有什么区别?为什么我们不使用花括号?
–郭世成
17年1月4日在19:25
@ShichengGuo使用分号,将在每个目录中找到一个rm命令,使用+单个rm命令将处理找到的所有目录(或至少其中很大的一个)。我没有第二个问题,卷曲在这里使用大括号。
– jlliagre
17年1月4日在20:13
我认为@ShichengGuo意味着我们为什么不需要在这里引用花括号(@jlliagre写道,我们永远不需要引用它们)。我现在找不到参考,但是我知道这是因为find会自动转义替换为{}的路径。
– Quinn Comendant
17 Mar 8 '17 at 6:47
答案和问题对+的作用不太正确。如果找到许多文件,则为“;”将给出“命令行太长”错误。 +分割小于最大允许命令行长度的批处理中找到的文件,并为每个批处理运行命令。
–gaoithe
17 Mar 22 '17 at 11:56
@gaoithe我确实回滚了您编辑的内容,其中用不正确的语句替换了正确的语句。使用+确实可以减少CPU使用率,使用;可以;不会导致命令太长的错误。
– jlliagre
17 Mar 22 '17 at 12:26
#3 楼
假设您使用的是gnu find,则可以使用-delete
选项:find . -name test -delete
,它更容易记住。
评论
考虑扩展您的帖子,并附上命令的说明(或文档以备份您的解决方案)。通常一(或两个)行答案不是最有启发性的。
– HalosGhost
2014年8月10日23:02
这不适用于非空目录。
– Belacqua
2014年12月16日20:47
在Mac OS X上也可以使用
–画
16-3-29在3:11
这不适用于非空文件夹,但这是更简单,更安全的解决方案
–卢梭·亚历山大(RousseauAlexandre)
18年2月7日在16:01
选项顺序非常重要,查找将按顺序执行它们,因此-delete必须是最后一个
–乔斯·伊格纳西奥·森特诺(Jose Ignacio Centeno)
18 Mar 6 '18 at 7:25
#4 楼
当我使用计算机时:find . \( -name dirname -type d \) -exec rm -r '{}' ';'
目录已删除,但出现错误:
find: ‘./dirname’: No such file or directory
对于每个目录。
我的目录不是空的,因此-delete选项对我不起作用。我在这里找到了这种现象的原因:
查找(不一定)在./目录中的第一个条目。这将是例如dir.1 /
将其与模式“ dir。?”进行比较。匹配吗?是。
find执行“ rm -r dir.1”。
find尝试输入dir.1 /以在目录中查找模式。它对exec命令一无所知。
它再也找不到dir.1 /。返回ENOENT(查看strace输出)
我改用此方法来解决:
rm -r `find . -name dirname -type d`
请记住,find仍将尝试递归到名为dirname的目录中,这实际上不是必需的,并且会花费一些时间。根据您的目录结构,您也许可以使用
--depth
查找选项解决此问题。另外,如果您具有目录名/目录名/ foo /目录名之类的目录结构,则会从rm中收到“无此文件或目录”错误。要消除错误,您可以将stderr重定向到/ dev / null或将rm用作-f
(force)标志。评论
坏主意:带空格的文件名会引起各种可怕的问题
–Clément
16年4月23日在15:31
对于将来的读者:查找。名称“要删除” -print0 | xargs -r0-rm -r是一个防故障版本,不会在空间上崩溃
–查理
16年7月20日在12:08
请参阅unix.stackexchange.com/a/115869/8257,您需要添加-prune。
– Mapio
17年1月29日在1:59
添加-prune以避免出现“无此类文件或目录”错误。
–朱利安·卡塞克(Julien Carsique)
17年2月24日在16:25
#5 楼
更快的方法是:find . -name ".svn" -type d -prune -exec rm -rf '{}' '+'
如果在另一个“ .svn”中包含“ .svn”。
评论
如果您要查找要删除的目录以及子目录,那不是很有用。
– Alexis Wilke
18年8月1日在7:47
使用-prune是最准确的方法。谢谢!
–alexandre1985
20年6月27日在15:10
#6 楼
重击特定解决方案:shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion
评论
请注意,对于与许多文件匹配的glob的命令行扩展,使用此机制可以匹配的文件数是有限制的。超过此限制将导致bash:/ bin / rm:参数列表过长
– Drav Sloan
2013年9月9日上午10:06
@DravSloan是正确的,但是该限制在数十万个文件中。这是要牢记的,但对于大多数人来说可能不是问题。
– evilsoup
2013年9月9日上午10:26
#7 楼
我发现-delete
动作与-path
测试配合得很好。例如,以下操作应该可以解决原始发布者问题:find . -path '*/.svn*' -delete
请注意,除了删除'.svn'目录(及其内容)之外,这还将删除其名称的所有文件或目录以“ .svn”开头。例如,如果您使用
-path '*/.git*'
,则除了“ .git /”外,还将删除“ .gitignore”和“ .gitattribute”。为避免这种情况,只需删除具有相同名称的目录,请使用:find . -path '*/.svn/*' -or -name '.svn' -delete
注意.svn后的斜杠。这将首先查找并删除“ .svn”下的所有文件,然后删除.svn目录本身。
评论
你确定吗? -delete表示-depth,它肯定会删除系统上的非空目录。
–马格努斯
17/12/20在13:56
重新测试,它可以工作。也许这只是我改正的错字。
– Kenorb
18年1月5日在22:23
我也尝试了这种方法,并且有效-目录已删除。
–艾伦
18年4月6日在8:38
#8 楼
TLDR find . -depth -name .svn -execdir rm -rf {} +
详细信息
使用
-execdir
而不是-exec
来自
man find
:使用-exec操作存在不可避免的安全问题;您应该改为使用-execdir选项。
在大多数情况下,
-execdir
可以替代-exec
。请使用
+
,而不要使用;
来自
man find
:与-exec操作一样,-execdir的'+'形式将建立一个命令行来处理多个匹配文件,但是任何给定的命令调用都只会列出存在于该文件中的文件。相同的子目录。
查找完全匹配的名称时,
+
和;
将执行相同的操作,因为在同一目录中不能有两个具有相同名称的文件,但是+
将在以下情况下提高性能多个文件/目录在同一目录中匹配您的find表达式。;
也需要从shell中转义,+
不需要转义。使用
-depth
从
man find
中:-depth
:在目录本身之前处理每个目录的内容。避免在删除目录后搜索目录。请参阅:
$ mkdir -p test/foo/bar
$ find test -name foo -execdir rm -rf {} +
find: ‘test/foo/bar’: No such file or directory
对:
$ mkdir -p test/foo/bar
$ find test -depth -name foo -execdir rm -rf {} +
# no error
评论
GNU find具有-delete选项。或者,您可以添加-exec rm -r“ {}” \;到发现的最后-使用rm -r时要小心! :)
@Marco Delete选项似乎不适用于目录。
@SuperChafouin在文件和目录上,它工作得很好。关键是它仅删除emtpy目录,并且当您指定-name“ .svn”时,它仅与.svn目录本身匹配,而不与.svn目录中的文件匹配。
@SuperChafouin,但不适用于其中带有空格的路径(因此使用带-exec并带有引号“ {}”的路径)。