管道回显输出到 xargs
Posted
技术标签:
【中文标题】管道回显输出到 xargs【英文标题】:Piping echo output into xargs 【发布时间】:2019-01-15 02:58:59 【问题描述】:我正在尝试通过xargs
传递值列表。这是一个简单的例子:
echo "Hello Hola Bonjour" | xargs -I _ echo _ Landon
我希望这会输出以下内容:
Hello Landon
Hola Landon
Bonjour Landon
相反,命令输出如下:
Hello Hola Bonjour Landon
我错过了什么?
【问题讨论】:
echo "Hello Hola Bonjour" | xargs printf '%s Landon\n'
不会有这个问题(因为printf
在看到额外参数时会重用其格式字符串,printf '%s Landon\n' Hello Hola Bonjour
将打印您期望的三行)。一般来说,最好避免使用xargs -I
;当应用于常见用例(例如替换为sh -c '...'
字符串)时,它存在严重的(安全)问题。
【参考方案1】:
-I
下,man xargs
说
未加引号的空格不会终止输入项;取而代之的是 分隔符是换行符
您可以指定不同的分隔符(至少在 GNU xargs 中):
printf 'Hello Hola Bonjour' | xargs -d' ' -I _ echo _ Landon
更便携,使用\0
作为分隔符,使用-0
:
printf '%s\0' Hello Hola Bonjour | xargs -0 -I _ echo _ Landon
【讨论】:
对 macOS 有什么建议吗?-d
标志不可用。
@LandonSchropp ...一般来说,最佳实践是使用 NUL 分隔符,而不是空格或换行符:printf '%s\0' Hello Hola Bonjour | xargs -0 -I _ echo _ Landon
。 NUL 是唯一不能存在于 C 字符串(文件名等)中的字符,因此它是唯一可以保证安全用于分隔任意字符串的字符; xargs -0
在 MacOS 上可用。
@LandonSchropp Mac 的 BSD 工具在很大程度上是不可移植的。你可以安装更便携的 GNU 版本,brew install findutils
。 This answer 有一些额外的细节。【参考方案2】:
分隔符需要更改,您还必须指定 -L 选项。因此,要么像建议的其他答案一样通过 -d 更改分隔符,要么通过管道 sed 并用换行符替换空格
echo "Hello Hola Bonjour" | sed -e 's/ /\n/g' | xargs -L 1 -I _ echo _ Landon
结果
Hello Landon
Hola Landon
Bonjour Landon
有时更改分隔符是不够的。 xargs 有时会获取所有输入参数并一次传递所有参数。没有拆分参数。
例如
seq 1 7 | xargs echo
结果
1
2
3
4
5
6
7
被传递给 xargs,所以输出将是
1 2 3 4 5 6 7
如果添加 xargs 手册页中显示的 -L 1
-L 最大线数 每个命令行最多使用 max-lines 非空白输入行。尾随空格导致输入行 逻辑上继续下一个输入行。隐含 -x。
seq 1 7 | xargs -L 1 echo
然后你会看到
1
2
3
4
5
6
7
您还可以手动将其转换为 for 循环,这样您就可以更轻松地设置多行语句。
# be absolutely sure the values the for loop iterates over is well sanitized to avoid glob expansion of the *.
for i in Hello Hola Bonjour
do
if [ "$i" = "Hello" ]
then
echo "$i Landon, language detected as English!"
else
echo "$i Landon, language detected as non English."
fi
done
【讨论】:
【参考方案3】:-I 标志将分隔符更改为换行符。
未加引号的空格不会终止输入项;而是分隔符是换行符。
你可以阅读它here。
您必须手动将分隔符指定为空格。默认情况下,Echo 还会插入一个换行符,这会弄乱 xargs。使用 -n 标志删除换行符。
这里是固定的命令:
echo -n "Hello Hola Bonjour" | xargs -d' ' -I _ echo _ Landon
【讨论】:
以上是关于管道回显输出到 xargs的主要内容,如果未能解决你的问题,请参考以下文章