这按预期工作:
$ echo a b c | xargs --replace="{}" echo x "{}" y
x a b c y
Run Code Online (Sandbox Code Playgroud)
这也可以:
$ echo a b c | xargs --max-args=1 echo x
x a
x b
x c
Run Code Online (Sandbox Code Playgroud)
但这并没有按预期工作:
$ echo a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a b c y
Run Code Online (Sandbox Code Playgroud)
这也没有:
$ echo a b c | xargs --delimiter=' ' --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c
y
Run Code Online (Sandbox Code Playgroud)
我期望这个输出:
x a y
x b y
x c y
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,我使用 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
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
根据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
Run Code Online (Sandbox Code Playgroud)
使用 POSIX 选项:
printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y
Run Code Online (Sandbox Code Playgroud)
在这里,我给出的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
Run Code Online (Sandbox Code Playgroud)
事实上,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
Run Code Online (Sandbox Code Playgroud)
这与 GNU coreutilsxargs
所做的(产生x a b c y
)不同。这是由于实现接受空格作为参数定界符-n
,即使使用, 也是如此-I
。所以,不要一起使用-I
和-n
(无论如何都不需要)。
小智 5
我发现的一项解决方法是将 的输出提供--max-args
给--replace
这样的:
echo a b c | xargs -n 1 | xargs -i echo firstPart {} secondPart
Run Code Online (Sandbox Code Playgroud)
这样就会输出。
firstPart a secondPart
firstPart b secondPart
firstPart b secondPart
Run Code Online (Sandbox Code Playgroud)
我想它基本上是循环输入并--max-args
默认添加新行字符。