这按预期工作:
$ echo a b c | xargs --replace="{}" echo x "{}" y
x a b c y
这也可以:
$ echo a b c | xargs --max-args=1 echo x
x a
x b
x c
但这并没有按预期工作:
$ echo a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a b c y
这也不是:
$ echo a b c | xargs --delimiter=' ' --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c
y
我期望这个输出:
x a y
x b y
x c y
作为解决方法,我使用 printf 和两个 xargs,但这很丑陋:
$ echo a b c | xargs printf '%s\0' | \
> xargs --null --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c y
知道为什么会发生这种情况吗?
答案1
根据POSIX 文档,xargs
应该运行给定的实用程序,参数由空格或换行符分隔,这就是您的前两个示例中发生的情况。
但是,当使用--replace
(或) 时,只有换行符会分隔参数。补救措施是在单独的行中-I
给出参数:xargs
$ printf '%s\n' a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c y
使用 POSIX 选项:
printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y
在这里,我xargs
不是一行,而是三行。它(最多)只需要一行,并以该行作为参数执行实用程序。
另请注意,上面的-n 1
(或--max-args=1
) 是不需要的,因为它的替换数量-I
决定了所使用的参数数量:
$ printf '%s\n' a b c | xargs -I "{}" echo x "{}" y
x a y
x b y
x c y
事实上,POSIX 规范的基本原理部分xargs
说(我的重点)
-I
、-L
和选项-n
是互斥的。如果在命令行上给出了多个,则某些实现会使用最后指定的一个;其他实现以不同的方式处理选项的组合。
在测试时,我注意到 OpenBSD 的版本如果和一起使用,xargs
将会执行以下操作:-n
-I
$ echo a b c | xargs -n 1 -I "{}" echo x "{}" y
x a y
x b y
x c y
这与 GNU coreutilsxargs
所做的不同(它产生x a b c y
)。这是因为-n
尽管-I
使用了,但实现仍接受空格作为参数分隔符。因此,不要将-I
and-n
一起使用(无论如何都不需要)。
答案2
--max-args
我发现的一项解决方法是将的输出提供给--replace
这样的:
echo a b c | xargs -n 1 | xargs -i echo firstPart {} secondPart
这样就会输出。
firstPart a secondPart
firstPart b secondPart
firstPart b secondPart
我想它基本上是循环输入--max-args
并默认添加新行字符。