实现递归rmdir的效果

实现递归rmdir的效果

据我所知,只有当参数的引用仅包含目录且树中任何位置不包含文件时,rmdir才可以选择 删除参数的引用。-r最简单的方法是什么?

答案1

GNUfind和当前的 BSD find(包括 macOS)有一个-delete可用于此目的的操作:

find . -type d -empty -delete

将找到所有空目录并将其删除。该-delete操作激活深度优先处理,因此仅包含其他目录且任何子目录中没有文件的目录将被删除。

答案2

您可以使用 zsh shell 将参数递归地扩展到(子)目录列表中,并按深度反向排序;然后rmdir可以按顺序处理列表。仅当每个目录为空时才会成功并提供警告(并且不是当目录不为空时删除该目录。这将导致删除空目录树并在目录不为空时发出警告。

我借用了该bydepth功能Stéphane 的回答在这里

bydepth() REPLY=${REPLY//[^\/]}
rmdir **/(/O+bydepth)

bydepth函数通过删除所有非正斜杠字符来(重新)设置 REPLY 变量。然后,glob 限定符中的排序函数使用该 REPLY 字符串O+对它们进行最长优先排序。另一个 glob 限定符是/,它仅选择目录。初始**/通配符告诉 zsh 从当前目录递归扩展。

样本运行:

$ : no files exist
$ mkdir -p a/b/c/d
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d
$ rmdir **/(/O+bydepth)
$ find .
.
$ 
$ : a file exists
$ mkdir -p a/b/c/d
$ touch a/b/c/somefile
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d
./a/b/c/somefile
$ rmdir **/(/O+bydepth)
rmdir: failed to remove ‘a/b/c/’: Directory not empty
rmdir: failed to remove ‘a/b/’: Directory not empty
rmdir: failed to remove ‘a/’: Directory not empty
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/somefile

相关内容