xargs:将 find 搜索的结果集执行某一指定命令。 当结果集数量过大时,可以分片映射。
find /usr/ -name '*tmp*' | xargs ls -l
一般情况下,文件名中没有空格,可以正常输出:
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.c' | xargs ls -l
-rw-rw-r-- 1 yugong yugong 12 6月 22 17:18 ./a.c
-rw-rw-r-- 1 yugong yugong 0 6月 22 16:52 ./dir/n.c
-rw-rw-r-- 1 yugong yugong 104 6月 23 20:58 ./file.c
-rw-rw-r-- 1 yugong yugong 30 6月 22 17:50 ./n.c
但,如果文件名中有空格,就不能正常输出:
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.txt' | xargs ls -l
ls: 无法访问'./1': 没有那个文件或目录
ls: 无法访问'file.txt': 没有那个文件或目录
ls: 无法访问'./2': 没有那个文件或目录
ls: 无法访问'file.txt': 没有那个文件或目录
分析过程如下:
find -print0
-print 打印 find命令 结果集,默认用换行符分割。而且 -print 是默认省略的。
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.txt'
./1 file.txt
./2 file.txt
-print0 打印 find命令 结果集,用 NULL 字符 ('\0')分割,而不是换行符。
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.txt' -print0
./1 file.txt./2 file.txt
xargs
xargs默认是以空白字符(空格、换行符、制表符)来分割记录的,实际上ls的数据便是 '
./1
' 和 'file.txt
' , './2
' 和 'file.txt
' 。
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.txt' | xargs ls -l
ls: 无法访问'./1': 没有那个文件或目录
ls: 无法访问'file.txt': 没有那个文件或目录
ls: 无法访问'./2': 没有那个文件或目录
ls: 无法访问'file.txt': 没有那个文件或目录
xargs -0表示xargs用NULL来作为分隔符
yugong@yugong-virtual-machine:~/zsy$ find ./ -name '*.txt' -print0 | xargs -0 ls -l
-rw-rw-r-- 1 yugong yugong 0 6月 24 19:59 ./1 file.txt
-rw-rw-r-- 1 yugong yugong 0 6月 24 19:59 ./2 file.txt
分析:第一个 -print0 指定结果集分隔为 null,第二个 -0 指定 xargs 分隔为 null。
find -print0表示在find的每一个结果之后加一个NULL字符,而不是默认加一个换行符。find的默认在每一个结果后加一个'\n',所以输出结果是一行一行的。当使用了-print0之后,就变成一行了。
然后xargs -0表示xargs用NULL来作为分隔符。这样前后搭配就不会出现空格和换行符的错误了。选择NULL做分隔符,是因为一般编程语言把NULL作为字符串结束的标志,所以文件名不可能以NULL结尾,这样确保万无一失。
让 find命令在打印出一个文件名之后接着输出一个 NULL 字符 ('\0') 而不是换行符, 然后再告诉 xargs 也用 NULL 字符来作为记录的分隔符。
参考链接: