如何使 xargs 使用 -n 附加尾随参数?

问题描述 投票:0回答:3

xargs 擅长插入初始参数:

seq 0 10 | xargs -n 3 echo foo

产生以下输出:

foo 0 1 2
foo 3 4 5
foo 6 7 8
foo 9 10

当我也想要尾随参数时怎么办? 也就是什么命令:

seq 0 10 | xargs -n 3 <WHAT GOES HERE?>

将产生以下所需的输出:

foo 0 1 2 bar
foo 3 4 5 bar
foo 6 7 8 bar
foo 9 10 bar

我尝试了以下方法:

seq 0 10 | xargs -n 3 -I {} echo foo {} bar

这几乎是正确的,除了它显然强制每个命令行 1 个项目,这不是我想要的:

foo 0 bar
foo 1 bar
foo 2 bar
foo 3 bar
foo 4 bar
foo 5 bar
foo 6 bar
foo 7 bar
foo 8 bar
foo 9 bar
foo 10 bar
xargs
3个回答
12
投票

在从 @netniV 的答案中抢先弄清楚这一点之后, 我现在看到手册页实际上包含一个示例 展示如何做:

xargs sh -c 'emacs "$@" < /dev/tty' emacs

启动所需的最小数量的 Emacs 副本,在 其他,编辑 xargs 标准输入上列出的文件。这个例子 达到与 BSD 的 -o 选项相同的效果,但以更灵活和可移植的方式。

并且wikipedia页面显示了类似的技术,最后对虚拟参数进行了解释:

实现类似效果的另一种方法是使用 shell 作为启动命令,并处理该 shell 中的复杂性,例如 示例:

$ mkdir ~/backups
$ find /path -type f -name '*~' -print0 | xargs -0 bash -c 'for filename; do cp -a "$filename" ~/backups; done' bash

行尾的单词

bash
bash -c
解释为特殊参数
$0
。如果 bash 这个词不存在,则名称 第一个匹配的文件将被分配给
$0
并且该文件不会 复制到
~/backups
。可以使用任何单词代替
bash
,但是 因为
$0
通常会扩展为 shell 或 shell 脚本的名称 被执行,
bash
是一个不错的选择。

所以,具体做法如下:

seq 0 10 | xargs -n 3 sh -c 'echo foo "$@" bar' some_dummy_string

输出如预期:

foo 0 1 2 bar
foo 3 4 5 bar
foo 6 7 8 bar
foo 9 10 bar

11
投票

使用xargs的-i参数如:

ls -1 | xargs -t -i echo "Found {} file"

请注意,-t 仅用于显示将发出的命令。实时运行时,请省略 -t 参数。

{}
被实际参数替换。请注意,这确实意味着每个命令每个文件仅运行一次。不是作为一组文件。如果需要使用不同的替换字符串,请在 -i

之后指定
ls -1 | xargs -t -i[] xargs echo "Found []{} file"

将在文件名后保留

{}
,现在在出现
[]

时被替换

达到想要的输出

创建一个名为 runme.sh 的脚本文件

#!/bin/sh
echo "foo $@ bar"

确保 chmod +X 然后使用

seq 0 10 | xargs -n 3 ./runme.sh

这会产生

foo tests tree.php user_admin.php bar
foo user_domains.php user_group_admin.php utilities.php bar
foo vdef.php bar

0
投票

我发现将对

xargs
的调用分成两部分要容易得多,就像这样

seq 0 10 | xargs -n 3 | xargs -I {} echo foo {} bar

第一个有一个隐式的

echo
命令,所以输出将是

0 1 2
3 4 5
6 7 8
9 10

而在第二个中,

-I
有一个隐式的
-L1
,一次选择一行,给出所需的输出

foo 0 1 2 bar
foo 3 4 5 bar
foo 6 7 8 bar
foo 9 10 bar
© www.soinside.com 2019 - 2024. All rights reserved.