使用 xargs --max-args --replace 与默认分隔符的问题

Ped*_*eno 8 linux gnu xargs

这按预期工作:

$ 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)

知道为什么会这样吗?

Kus*_*nda 6

根据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默认添加新行字符。