如何删除所有具有特定名称的子目录

7

我是一名Linux用户,有一个包含许多子目录的文件夹。我需要删除所有具有相同名称的子目录。例如,

dir
 |---subdir1
 |---subdir2
 |     |-----subdir1
 |---file

我想要删除全部的subdir1目录。以下是我的脚本:

find dir -type d -name "subdir1" | while read directory ; do
    rm -rf $directory
done

然而,我执行了它,但似乎什么也没有发生。

我还尝试过 find dir -type d "subdir1" -delete,但仍然没有任何反应。


1
find dir -type d -name "subdir1" 能正确地列出文件夹吗? - Inian
@Inian 是的,它确实有这个功能。 - Yves
1
将“--delete”更改为“-delete”。 - Tom Fenech
@TomFenech 没有任何变化... - Yves
你确认你拥有删除目录及其所有内容的权限吗? - MarcM
@MarcM 是的。我使用 rm -rf dir/subdir1 来删除其中一个,并且它有效。我不需要执行 sudo - Yves
4个回答

13

如果find能够正确找到目录,以下命令应该可行:

find dir -type d -name "subdir1" -exec echo rm -rf {} \; 
或者
find dir -type d -name "subdir1" -exec echo rm -rf {} +

("echo"用于验证命令是否作用于所需文件,要运行 "rm" 并删除目录,请将其删除。)

将管道导入 "xargs" 和 "while read" 都有一个缺点,即不寻常的文件名会引起问题。另外,“find -delete” 仅尝试删除目录本身,而不是它们的内容。它将无法处理任何非空目录(但至少应该会出现错误)。

使用 "xargs",默认情况下,空格分隔单词,因此即使带有空格的文件名也无法工作。"read" 可以处理空格,但在您的命令中,未加引号的扩展 "$tar" 在空格上拆分了变量。

如果您的文件名没有换行符或尾随空格,这也可以起作用:

find ... | while read -r x ; do rm -rf "$x" ; done

我能看到从 echo 发来的消息,但所有来自 subdir1 的消息总是存在。这是由于某些格式问题或权限问题造成的吗?dir 来自 Windows 系统,并且有许多不寻常的文件名,例如包含 & 的名称。 - Yves
@Yves,如果您删除echo并实际运行rm命令,是否会出现任何错误? 只要系统的其他部分没有问题,find -exec不应该对不寻常的文件名有任何影响。 - ilkkachu

6

使用 globstar 选项(通过执行 shopt -s globstar 开启,需要 Bash 4.0 或更高版本):

rm -rf **/subdir1/

这种解决方案与使用“find -exec”或“find | xargs”相比的缺点是参数列表可能会变得太长,但这需要很多名为“subdir1”的目录。在我的系统上,“ARG_MAX”为2097152。

2

使用xargs:

find dir -type d  -name "subdir1" -print0 |xargs -0 rm -rf

与问题/问题无直接关系的一些信息:

find|xargsfind -exec

https://www.everythingcli.org/find-exec-vs-find-xargs/

意思是:在IT技术中,有两种常用的方式来处理查找文件并对其执行操作。第一种是使用 "find" 命令和管道符号 "|" 结合 "xargs" 命令;第二种是使用 "find" 命令的 "-exec" 选项。这篇文章将介绍这两种方法的区别和使用场景。

1
正是我要回答的内容。但请考虑使用 find -print0xargs -0 来处理文件名中包含空格的情况。 - slim
如果你想回答"-exec"选项的问题,就请回答吧(我会点赞)。"xargs"可以使用并重复在很多情况下。 - slim
1
@Kent 看起来写了“xargs vs. exec”博客文章的那个人错过了使用“-exec ls {} +”的机会。 - hek2mgl
1
@hek2mgl 谢谢您。我已经在回答中放置了链接,并且由于您的评论,我今天学习了exec + - Kent
1
@hek2mgl,我刚刚找到了GNU findutils的变更日志,并且"-exec ... {} +"是在2005年添加的。那已经是很久以前的事情了,但是在我学习shell脚本之后不久就出现了这个功能。使用"\0"管道传输到xargs会稍微快一些,根据我的简单基准测试,这有些合理,因为它稍微并行化了一些东西,但我同意"-exec ... {}"可能被视为更清晰的选项。 - slim
显示剩余14条评论

0
从问题来看,似乎您尝试使用whilefind。以下替换可能会对您有所帮助:

while IFS= read -rd '' dir; do rm -rf "$dir"; done < <(find dir -type d -name "subdir" -print0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接