我不太熟悉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
逻辑运算符。)