这按预期工作:
$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
知道为什么会这样吗?
解决方法:
根据the POSIX documentation,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
事实上,关于xargs的POSIX规范的基本原理部分(我的重点)
The
-I
,-L
, and-n
options are mutually-exclusive. Some implementations use the last one specified if more than one is given on a command line; other implementations treat combinations of the options in different ways.
在测试时,我注意到如果-n和-I一起使用,OpenBSD的xargs版本将执行以下操作:
$echo a b c | xargs -n 1 -I "{}" echo x "{}" y
x a y
x b y
x c y
这与GNU coreutils的xargs(产生x a b c y)不同.这是因为实现接受空格作为带-n的参数分隔符,即使使用-I也是如此.所以,不要一起使用-I和-n(无论如何都不需要).