如果我创建以下目录结构:
mkdir -p dir1/dir2/dir3/dir4
Run Code Online (Sandbox Code Playgroud)
然后我运行find dir1,它返回:
dir1
dir1/dir2
dir1/dir2/dir3
dir1/dir2/dir3/dir4
Run Code Online (Sandbox Code Playgroud)
如果我运行find dir1 -empty,它只返回:
dir1/dir2/dir3/dir4
Run Code Online (Sandbox Code Playgroud)
显示只有 dir4 是空的。
但是,如果我运行find dir1 -empty -delete,所有四个目录都会立即删除。
我希望只删除 dir4,然后下次运行命令时,只删除 dir3,依此类推。为什么会发生这种情况,以及如何使用 仅删除 dir4 find?
ilk*_*chu 12
因为-delete意味着-depth,或深度优先迭代,所以find首先查看dir1/dir2/dir3/dir4,注意到它是空的,删除它,然后查看dir1/dir2/dir3,注意到它(现在)是空的并删除它......
-depth
在目录本身之前处理每个目录的内容。该-delete动作也暗示-depth。
这可能是他们认为能够删除一些文件然后可能包含这些文件的目录如果同时被清空(-delete不会递归删除整个子树)更常见,而不是必须重复该find命令,直到所有匹配的文件和目录都没有了。或者换个角度看,只删除树的叶子(正如我们在这里想要的)不是幂等的:不小心再次运行命令会从目录树中剥离另一层。
在任何情况下,您都可以find运行rmdir以保持默认模式,并添加-prune以防止它尝试下降到现已删除的目录中。让-print我们也在这里添加调试,所以我们看看它删除了什么:
$ mkdir -p dir1/dir2/dir3/dir4
$ find -type d -empty -exec rmdir {} \; -prune -print
./dir1/dir2/dir3/dir4
Run Code Online (Sandbox Code Playgroud)
这就是剩下的:
$ find
.
./dir1
./dir1/dir2
./dir1/dir2/dir3
Run Code Online (Sandbox Code Playgroud)
(此处,如果rmdir失败,则-exec操作评估为假,并且-prune和-print操作将不会运行。因此,打印到标准输出的内容应仅包含实际删除的内容。这与-exec rmdir {} +.不同。)
当然,假设您只想在这里删除空目录,如果您还想删除空文件,则可以先使用
find -type f -empty -delete
Run Code Online (Sandbox Code Playgroud)
或者构建调用rm文件和rmdir目录的可怕组合:
find -empty \( -type f -exec rm {} \; -o -type d -exec rmdir {} \; -prune \) -print
Run Code Online (Sandbox Code Playgroud)
(rm -rf显然也可以工作,但风险更大。)