删除空目录树(删除尽可能多的目录,但不删除文件)


13

假设我有一个这样的目录树:

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

我正在寻找这样的命令,当我输入:

$ [unknown command] ROOTDIR

如果没有文件,而整个树内部只有目录,则可以删除整个目录。但是,说一下SUBDIR1下是否有一个名为hello.pdf的文件:

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

然后,该命令只能删除SUBDIR2及以下版本。


Answers:


11

亚历克西斯很近。您需要做的是:

find . -type d -depth -empty -exec rmdir "{}" \;

这将首先向下钻取目录树,直到找到第一个空目录,然后将其删除。因此,使父目录为空,然后将其删除,等等。这将产生所需的效果(我可能每周执行10次,所以我很确定这是正确的)。:-)


为什么需要-depth选择?find . -type d -empty -exec rmdir "{}" \;应该也可以....对吗?
Abhishek A

4
考虑一下您是否有一棵树(仅目录)foo/bar/baz。除非您使用-depth,否则它将foo首先尝试删除,然后失败,然后foo/bar在运行后最终消失。
l0b0 2011年

1
可能的替代方法是使用+而不是,;以便您批量删除目录。由于您是深度优先的,因此仍然会在父级之前删除子级(可能取决于您的rmdir / bash版本,并且依赖rmdir不会删除非空目录)。这对我在cygwin上的bash mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
有用

4
亲爱的,下面去go2null的答案要简洁得多!无法理解为什么SE在显示问题下方的答案时会优先考虑已接受的答案,而不是大多数投票否决的答案。OP会在选择时接受最佳答案,但是稍后会出现更好的答案,社区会支持,不是吗?(当然,这是元数据。)
jamadagni 2014年

这对我不起作用。它只会删除最深的叶子(在这种情况下为SubDIR3)
Joey Baruch

24
find ROOTDIR -type d -empty -delete

如同

find ROOTDIR -type d -depth -empty -exec rmdir "{}" \;

但使用内置的“-删除”操作。

注意,“-删除”表示“-深度”。


通过使用find自己的内置删除功能,获得最简洁的答案!我将此添加到我的本地脚本中!
jamadagni 2014年


1

在安全地进行操作之前,有一些要求:

  1. 首先删除子目录,然后再删除上级目录,即我们需要对目录列表进行排序或使用rmdir --parents标志
  2. 始终使用/或./来启动ROOTDIR,以避免以-开头的文件出现意外
  3. 使用NUL终止的目录列表来处理带空格的目录名称

这是我在shell中的方法:

find ./ROOTDIR -type d | sort -r | tr '\n' '\000' | xargs -0 rmdir --ignore-fail-on-non-empty

如果您不介意一些多余的错误,则可以强制删除所有带有父目录的目录,而无需进行任何排序(您不能对NUL终止的字符串进行排序,这会增加tr的需要)

find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents

感谢您对答案的详细解释。在我了解@ go2null答案中的-empty -delete选项之前,我可能会使用相同的方法find
达沃·库伯拉尼克

0
rmdir $(find ROOTDIR -type d | sort -r)

5
如果任何目录名包含空格或通配符,则此方法将无效。在文件名列表上使用命令替换通常是一个坏主意。这是一个绝妙的主意,find因为它find有一种方法可以干净地进行处理:find … -exec
吉尔(Gilles)“所以,别再邪恶了”,

感谢Gilles指出这一点。@lanzz,通常仅发布命令而不解释其功能(在这种情况下,就是陷阱)是不够的。请添加到您的答案。
n0pe

0

我会这样做:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
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.