`find -delete` 删除了所有内容

`find -delete` 删除了所有内容

我不太熟悉find并意外删除了大量文件。我想知道是否有更有经验的人可以解释我哪里出错了。


我想清理MacBook 的 Finder 在我的 Raspbian samba 共享中吐出的所有文件.DS_Store._.DS_Store

  • 我有一个硬盘驱动器连接到我的树莓派,我的主文件夹中有一些符号链接到安装点,因此-L.
  • 一些文件夹由系统用户(例如 apache)拥有,因此 sudo.

我运行了以下命令以确保find目标文件正确:

hydraxan@raspberry:~ $ sudo find -L . -maxdepth 255 -name \*DS_Store\*
./.DS_Store
./Downloads/USBHDD1/._.DS_Store
./Downloads/USBHDD1/.DS_Store
./Downloads/USBHDD1/backups/ALAC/._.DS_Store
./Downloads/USBHDD1/backups/ALAC/Jeff Van Dyck - Assault Android Cactus OST/._.DS_Store
./Downloads/USBHDD1/backups/ALAC/Jeff Van Dyck - Assault Android Cactus OST/.DS_Store
./Downloads/USBHDD1/backups/ALAC/.DS_Store
./Downloads/USBHDD1/backups/._.DS_Store
./Downloads/USBHDD1/backups/.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/._.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/.DS_Store
./Downloads/USBHDD1/backups/OriginalMusic/FLAC/.DS_Store
./Downloads/USBHDD1/backups/Storage/._.DS_Store
./Downloads/USBHDD1/backups/Storage/.DS_Store
./Downloads/OriginalMusic/._.DS_Store
./Downloads/OriginalMusic/.DS_Store
./Downloads/OriginalMusic/FLAC/.DS_Store
./Downloads/ALAC/._.DS_Store
./Downloads/ALAC/Jeff Van Dyck - Assault Android Cactus OST/._.DS_Store
./Downloads/ALAC/Jeff Van Dyck - Assault Android Cactus OST/.DS_Store
./Downloads/ALAC/.DS_Store

一切看起来都不错!

然后我添加了-delete标志以find删除它找到的文件:

hydraxan@raspberry:~ $ sudo find -L . -maxdepth 255 -delete -name \*DS_Store\*
find: cannot delete `./Documents': Not a directory
find: cannot delete `./Pictures': Not a directory
find: cannot delete `./Music': Not a directory

当我意识到它出于某种原因试图删除我的符号链接时,我猛击Ctrl+C并保存了大约一半的数据。

文档、图片和音乐都完了。它可能正在我巨大的下载文件夹中运行,我几乎把所有东西都放进去了。


为什么find删除所有这些文件?我是不是放-delete错地方了?

答案1

您的答案在find联机帮助页中。

删除选项在您的名称过滤器之前处理。

       -delete
          Delete files; true if removal succeeded.  If the removal failed,
          an  error message is issued.  If -delete fails, find's exit sta‐
          tus will be nonzero (when it eventually exits).  Use of  -delete
          automatically turns on the -depth option.

          Warnings:  Don't  forget that the find command line is evaluated
          as an expression, so putting -delete first will make find try to
          delete everything below the starting points you specified.  When
          testing a find command line that you later intend  to  use  with
          -delete,  you should explicitly specify -depth in order to avoid
          later surprises.  Because -delete  implies  -depth,  you  cannot
          usefully use -prune and -delete together.

您可以将删除选项移至命令的最后一个

或者,你可以使用类似的东西

find /path -name "*pattern*" | xargs rm -f

或者

find /path -name "*pattern*" -exec rm -f {} \;

答案2

命令行的基本原则find是“if条件和条件然后……然后采取行动”。请注意,操作位于最后 - 它与调用命令“操作对象对象...”的格式有很大不同。

例如,find . -name \*DS_Store\* -delete表示“如果名称匹配*DS_Store*则删除”。如果颠倒条件和操作,则-delete操作后面没有条件,因此会无条件应用。

之所以find . -delete -name \*DS_Store\*不是语法错误是因为动作也是条件。如果操作成功,则该-delete操作为 true 条件;如果失败(例如,由于缺乏权限),则该操作为 false。例如,find . -name somethingorother -delete -print打印成功删除的文件的名称。

之所以find -name \*DS_Store\*不是语法错误,是因为如果没有动作,那么就有隐式-print动作。之所以这样设计,是因为打印是一种非常常见的操作选择。

(请注意,虽然我的答案不包含彻头彻尾的谎言,但它确实简化了一些事情。有些功能是find我的答案中的解释未涵盖的,特别是!-o逻辑运算符。)

相关内容