find ~ -name delete_me -type f -print0 | xargs -0 /bin/rm -f
Q1.这是什么意思-print0
,为什么需要它?
Q2./bin/rm
为什么?为什么不只是rm -f
?
该命令只删除~
目录中匹配的文件;它不会删除子目录或子子目录中的匹配文件。
Q3。如何修改它以便它也能找到并删除子目录中所有匹配的文件?
Q4。如何修改使其找不到某个目录?
谢谢
答案1
非标准
-print0
谓词的意思是“打印找到的文件的路径名,末尾带有终止 nul 字符而不是换行符”。这是为了能够处理包含换行符的文件名(Unix 系统上允许;但是 nul 字符不能是 Unix 文件名的一部分)。读取find
所使用命令的输出的命令-print0
需要注意条目是以 null 结尾的。该-0
选项允许xargs
它读取以 null 结尾的条目。这不是必需的。两者都不是
find "$HOME" -name delete_me -type f -delete
也不是更标准的
find "$HOME" -name delete_me -type f -exec rm {} +
使用
-print0
.这两个命令与您的命令执行相同的操作,并且应该优先使用xargs
.xargs
从文件或其他命令读取参数时,该实用程序可能很有用。使用时find
,使用其内置-exec
设施更安全。那里是有一些事情是某些实现xargs
可以做而不-exec
能做的,比如启动并发批次的实用程序。然而,本练习中并未使用这一点。最好在 shell 脚本中使用它,因为
"$HOME"
它的行为类似于变量,但事实并非如此。~
$HOME
~
另请注意,可能不需要该
-f
选项。rm
它用于避免rm
实用程序失败(带有诊断消息和非零退出状态)如果给定的路径名丢失,或者rm
调用时没有要删除的路径名。它还会覆盖任何早期的-i
(交互模式)选项。但是这里的命令行-i
上没有选项rm
,并且给定的路径名保证在find
用于查找它们时存在(除非出现竞争条件,其中文件在执行期间被find
其他进程实际删除,在由并被 )的执行者find
删除。rm
find
没有理由使用
rm
其完整路径,除非PATH
不能保证变量的值包含一组合理的实用程序路径。损坏的情况并不常见PATH
,并且使用绝对路径编写实用程序的脚本在移动到其他系统时很容易损坏。它确实已经递归到主目录的所有子目录中。
从搜索树中删除您想要避免的目录。例如,要避免所有名为的目录
avoid
:find "$HOME" -name avoid -prune -o -name delete_me -type f -exec rm {} +
请注意,我们不能
-delete
在这里使用,因为这意味着-depth
深度优先搜索。通过深度优先搜索,我们将访问其中的所有子目录和文件,avoid
然后才注意到avoid
应该从搜索树中删除该目录。另一个例子:不要进入具体的目录
$HOME/dir/save_me
:find "$HOME" -path "$HOME/dir/save_me" -prune -o -name delete_me -type f -exec rm {} +
答案2
Q1.-print0是什么意思,为什么需要它?
一个好的起点是查看手册。在终端上,您可以输入man find
以获得详细的描述。通常,您也可以通过谷歌搜索“man find”并在网络上获取相同/相似的手册页。
find 的手册说-print0
:
在标准输出上打印完整的文件名,后跟一个空字符(而不是 -print 使用的换行符)。这允许处理查找输出的程序正确解释包含换行符或其他类型空格的文件名。
因此,这将写入每个文件名,后跟一个空字符和 xargs-0
将读取,期望每个项目以-0
.这允许文件名包含换行符。
Q2.为什么是/bin/?为什么不只是 rm -f ?
从你的问题来看,尚不清楚为什么这样做。
看来这确实没有什么充分的理由。有时这样做的原因之一是让您在小路环境变量设置不正确。在 in 中运行命令时,这种情况很常见cron
。
然而,在这种情况下,它没有任何帮助,因为其他命令(find
和xargs
)不完全限定。它应该是:
/bin/find ~ -name delete_me -type f -print0 | /usr/xargs -0 /bin/rm -f
唯一的另一个(极不可能)原因是您的系统以某种方式有两个不同的rm
命令,您需要指定哪一个。但这确实不太可能。
Q3。如何修改它以便它也能找到并删除子目录中所有匹配的文件?
它已经这样做了。
Q4。如何修改使其找不到某个目录?
您可以使用该-prune
选项跳过该目录(及其子目录)。
# Just editing your version...
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -print0 | xargs -0 /bin/rm -f
# More succinctly
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -exec rm -f {} +