xargs如何格式化$'\n'的输入?

How does xargs format the input of $'\n'?

问题

(1) 给定一个字符串,我使用 sed:

将空格替换为 $'\n'
echo "one two" | sed 's/ /$'"'"'\n'"'"'/g'

这输出:

# one$'\n'two

(2) 请注意,回显 (1) 的输出:

echo one$'\n'two

结果:

# one
# two

(3) 我以另一种方式回显 (1) 的输出,通过将 (1) 的输出输送到 xargs echo:

echo "one two" | sed 's/ /$'"'"'\n'"'"'/g' | xargs echo

但我没有得到与 (2) 相同的输出:

# one$\ntwo

问题

格式化包含 $'\n' 的字符串输入时,xargs 做什么?

为什么用 $'\n' 回显字符串与在同一字符串上使用 xargs echo 不同?

写的时候

echo one$'\n'two

在命令行中,bash 将“$'\n'”替换为换行符。但是当你将它传递给 xargs 时,不会发生这样的替换。

但是通过管道传输到 xargs 仍然 不会做你想做的事,因为默认情况下 xargs 使用换行符作为参数分隔符:

$ echo "one two" | tr ' ' '\n' | xargs echo
one two

你必须告诉 xargs 使用不同的分隔符,即使它是假的:

$ echo "one two" | tr ' ' '\n' | xargs -0 echo
one
two

不确定是否回答了你的问题,但我过去在类似情况下使用的一个技巧是使用 printf 来代替,它循环遍历循环中传递的参数(如果不够 % 消耗它们),例如:

$ printf "%s\n" one two
one
two

使用shell自己的白色-space分隔符如果以上是一个字符串

$ args="one two"
$ printf "%s\n" $args
one
two

为了完整起见,用一些 foo scriptlet

提供给 xargs -n1
$ printf "%s\n" one two |xargs -n1 sh -c 'echo [$(date -R)] foo=' --
[Sun, 03 Jun 2018 21:34:17 -0300] foo=one
[Sun, 03 Jun 2018 21:34:17 -0300] foo=two