删除空的子文件夹,保留父文件夹


15

当我使用

find /home/user/parentdir -type d -empty -delete

它递归地查找内部的空子文件夹/home/user/parentdir并将其删除。但是如果/home/user/parentdir也为空,它也会删除该parentdir文件夹,这对我来说是不可取的。

我想将其保留parentdirrsync一些要备份或云的文件中。处理后,我需要删除空文件夹,但是parentdir每次重新创建似乎都没有用。

parentdir什么建议要保留吗?我曾考虑过在其中创建.nocopy文件并将其从中排除rsync,但看起来有点过头了。有没有更优雅的方式?


如果在/ parentdir(即/ parentdir /)的末尾添加正斜杠/,会有所不同吗?
格雷厄姆

6
-mindepth 1
steeldriver

@Graham / parentdir /也会删除parentdir,所以没有区别。
TNT

啊,我看到我错过了@Amourk在回答中提到的末尾的*。
格雷厄姆

Answers:


25

简单地做find /home/user/parentdir -mindepth 1 -type d -empty -delete

看:

$ mkdir -p test1/test2
$ find test1 -type d
test1
test1/test2
$ find test1 -mindepth 1  -type d
test1/test2

find /home/user/parentdir/* 在AmourK的答案时,有很多的文件,它是过于复杂是不可取的。


15

通过添加/*到的末尾parentdir,您将对parentdir的所有子目录(而不是对parentdir自身)执行操作。因此,以同样的方式/home/user/不会在旧命令中删除,parentdir也不会在下面的命令中删除。 *被称为全局运算符,它与任何字符串匹配。

find /home/user/parentdir/* -type d -empty -delete


7
这种方法要注意的一件事是,如果中有大量文件/home/user/parentdir/,扩展的glob可能会超过ARG_MAX,导致参数列表过长的错误。您可以通过将glob更改为*/只与目录匹配来减少发生这种情况的机会。
steeldriver'sep

12
还要注意,这将找不到任何以点开头的子级。有一天,您将意识到这一点,如果您也找到“。*”,您将遭受巨大的伤害(因为“。*”匹配“ ..”)。问我我怎么知道。
格伦·威伦

1
@GlennWillen为什么我要求我们讲这个故事之前,为什么我们应该坐在我们面前的酒吧里喝酒?
蒙蒂·哈德

@MontyHarder幸运的是,它并没有想象中的那么糟糕。它在我的第一个Unix系统上,那是我高中时拥有的Solaris计算机。谢天谢地,我不是在运行“ rm”,而是在运行“ chown”。我使用root尝试修复主目录中所有内容的所有权。取而代之的是,我给了自己每个主目录(及其所有内容)的所有权,然后不得不将它们全部放回原处。
格伦·威伦

我有一位同事在培训新员工如何安装软件。它涉及到/tmp,创建子目录,在那里解压缩压缩包,运行安装程序并清理。新手认为这rm -rf /tmp/foo-install是正确的方法,而经验丰富的手在他对《第三纪》结尾的最佳达斯·瓦德(Darth-Vader)印象中说“ Noooooo”时,新手发现了很难接近/和Enter键是彼此的。我们必须从备份软件的还原磁盘启动,然后从磁带重新加载整个服务器。
蒙蒂·哈德

0

如果您安装了php-cli,

printf %s $(pwd) | php -r 'function f(string $dir){var_dump($dir);$dir.=DIRECTORY_SEPARATOR;foreach(glob("$dir*",GLOB_ONLYDIR) as $d){f($d);}global $original;if(substr($dir,0,-strlen(DIRECTORY_SEPARATOR))!==$original && empty(glob("$dir*"))){rmdir($dir);}}f(($original=stream_get_contents(STDIN)));'

您想要的foreach (RecursiveIteratorIterator(RecursiveDirectoryIterator($dir)) as $p) if (empty($skipped)) $skipped = TRUE; elseif ($p->isDir()) @rmdir($p->getPathname());东西或接近它的东西。$skipped注意跳过第一个,@rmdir尝试删除目录,如果不为空,则尝试静默(即@)失败。
chx

0

如果只需要一个级别(保留一个父文件夹,但删除空的子文件夹),则可以使用一个简单的技巧rmdir

rmdir parent/*

删除所有空的子文件夹,但仅显示文件和非空文件夹的错误。

这不是递归的,但是当知道您的文件夹结构时,这可能是最快的方法,例如

rmdir parent/*/*/* # deletes parent/a/b/c when empty
rmdir parent/*/* # deletes parent/a/b when it is now empty
rmdir parent/* # deletes parent/a when it is now empty

优点:易于记忆,键入速度快,选择错误参数的可能性很小。
缺点:灵活性较差,终端中可能会出现很多错误消息。

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.