find -print0和xargs -0

通常我们将findxargs搭配使用:

find . -name "*.txt" | xargs rm

但是这个命令如果遇到文件名里有空格或者换行符,就会出错。因为xargs识别字符段的标识是空格或者换行符,所以如果一个文件名里有空格或者换行符,xargs就会把它识别成两个字符串,自然就出错了。
下面我们创建例子进行测试说明:

[root@localhost test]# touch "a.txt"
[root@localhost test]# touch "b.txt"
[root@localhost test]# touch "c d.txt"
[root@localhost test]# touch "e
> f.txt"
[root@localhost test]# ll
总用量 0
-rw-r--r-- 1 root root 0 12月  7 12:25 a.txt
-rw-r--r-- 1 root root 0 12月  7 12:24 b.txt
-rw-r--r-- 1 root root 0 12月  7 12:22 c d.txt
-rw-r--r-- 1 root root 0 12月  7 12:26 e?f.txt
[root@localhost test]#

此时,我们执行find . -name "*.txt" | xargs rm,看看结果如何。

[root@localhost test]# find . -name "*.txt" | xargs rm
rm: 无法删除"./c": 没有那个文件或目录
rm: 无法删除"./d.txt": 没有那个文件或目录
rm: 无法删除"./e": 没有那个文件或目录
rm: 无法删除"f.txt": 没有那个文件或目录

这时候就需要-print0和xargs -0了。
find -print0表示在find的每一个结果之后加一个NULL字符,而不是默认加一个换行符。find的默认在每一个结果后加一个'\n',所以输出结果是一行一行的。当使用了-print0之后,就变成一行了。

[root@localhost test]# find . -name "*.txt" -print0
./e
f.txt./c d.txt[root@localhost test]#

然后xargs -0表示xargs用NULL来作为分隔符。这样前后搭配就不会出现空格和换行符的错误了。选择NULL做分隔符,是因为一般编程语言把NULL作为字符串结束的标志,所以文件名不可能以NULL结尾,这样确保万无一失。

[root@localhost test]# find . -name "*.txt" -print0 | xargs -0
./e
f.txt ./c d.txt

因此,为了确保不会出现以上问题,推荐使用的命令:

[root@localhost test]# find . -name "*.txt" -print0 | xargs -0 -I {} rm -vf {}
已删除"./e\nf.txt"
已删除"./c d.txt"

你可能感兴趣的:(find -print0和xargs -0)