执行命令时find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-zA-Z]+\.txt
,会返回以下结果。
./testfile.txt
./testread.txt
相比之下,命令find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-zA-Z]+\.txt' -print0
输出./testfile.txt./testread.txt
为单行,据我了解,标志条-print0
带/替换\n
为NUL
或\0
使用它们作为分隔符。
xargs
当后面的命令和参数按如下方式传递时find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-zA-Z]+\.txt' -print0 | xargs -0 -i echo {}
,显示
./testfile.txt
./testread.txt
我假设不需要'{}'
后续的操作,因为使用了标志并且处理空格等字符没有错误。echo
-print0
下面的命令都生成一行。
find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-zA-Z]+\.txt' -print0 | xargs -0
find . -maxdepth 1 -regextype posix-egrep -regex '.*/[a-zA-Z]+\.txt' -print0 | xargs -0 echo
为什么xargs
with{}
返回的结果带有换行符?
如果{}
附加一个新行字符,为什么将其与命令结合使用,例如echo {}
?
答案1
对于 GNU xargs
,该-i
选项(已弃用)与 相同-I {}
。这意味着“将实用程序中出现的字符串替换{}
为标准输入中的一项,然后运行该实用程序并使用标准输入中的下一项重复”。
您的实用程序调用是echo {}
,并且您将两件事传递给xargs
.这意味着调用echo
两次,每次都从标准输入读取其中一项。每次调用都会输出echo
一个尾随换行符(这是 的一个功能echo
)。
如果没有echo {}
和-i
,xargs
将从标准输入中收集尽可能多的项目并输出它们,就好像它echo
同时调用了所有项目一样。
简而言之,xargs
不添加换行符,echo
而是添加换行符。它这样做是因为您多次调用它。
示例(-t
添加后可以xargs
显示它的作用):
$ printf 'file1\nfile2\n' | xargs -t -I {} echo {}
echo file1
file1
echo file2
file2
$ printf 'file1\nfile2\n' | xargs -t echo
echo file1 file2
file1 file2
答案2
换行符由echo
,添加不是经过xargs
。
使用时的差异-i
是因为此选项强制-L 1
(一行,或每个命令一个空分隔字段)。因此,echo
每个输入字段运行一次,因此字段之间有一个换行符(echo
通常在完成时添加一个换行符)。
如果没有-i
,因此没有-L 1
,每个 echo 都会接收更多字段,因此大多数字段都用空格分隔(echo 连接其参数,用空格分隔)。