find -delete 不删除非空目录

sds*_*sds 46 osx find

命令

$ find ~ -name .DS_Store -ls -delete
Run Code Online (Sandbox Code Playgroud)

适用于 Mac OS X,但

$ find ~ -name __pycache__ -type d -ls -delete
Run Code Online (Sandbox Code Playgroud)

没有 - 找到目录但未删除。

为什么?

附注。我知道我能做到

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +
Run Code Online (Sandbox Code Playgroud)

问题是,为什么 find -delete工作。

GnP*_*GnP 46

find-delete标志与rmdir删除目录时类似。如果目录在到达时不为空,则无法删除。

您需要先清空目录。由于您正在指定-type dfind因此不会为您执行此操作。

您可以通过执行两遍来解决此问题:首先删除 dirs named 中的__pycache__所有内容,然后删除所有 dirs named __pycache__

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete
Run Code Online (Sandbox Code Playgroud)

控制不那么严格,但在一行中:

find ~ -path '*/__pycache__*' -delete
Run Code Online (Sandbox Code Playgroud)

这将删除您家中__pycache__作为其路径一部分的任何内容。

  • @naught101,应该是`find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -delete` 因为_and_ 优先于_or_。 (3认同)

phe*_*mer 8

这有几个潜在的原因。

1) 您告诉它只删除目录 ( -type d),而这些目录中仍然有文件。

2) 您的目录仅包含其他目录,因此-type d将处理内容问题。但是,您使用的是 OS-X,它主要基于 FreeBSD,并且 FreeBSDfind默认会先处理目录,然后再处理其内容。
但是,-depth存在通过告诉find在目录内容之后处理目录来解决此问题的选项。

find ~ -name __pycache__ -type d -ls -delete -depth
Run Code Online (Sandbox Code Playgroud)

这个问题在 linux 上不存在,因为该-delete选项隐式启用-depth.

 

自由BSD man 1 find

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.
Run Code Online (Sandbox Code Playgroud)

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是 [FreeBSD 的 find(1)](https://www.freebsd.org/cgi/man.cgi?query=find(1)) 说 **`-delete`**,“......深度优先这个选项暗示了遍历处理。”,[GNU find(1)](http://linux.die.net/man/1/find) 说,“...... **-delete** 意味着 **-depth **, ...”,因此不需要在命令中添加 **`-depth`**。 (2认同)