Xargs `-J` 选项

Xargs `-J` 选项

这个网站xargs命令提供一个-J选项,使得能够将标准输入传递到命令参数处的所需位置:

find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/

但在一个GNU xargs 手册页该选项不存在。

对于接受此操作的命令,执行此操作的方法是什么?

答案1

我不确定这是否是您所期望的,但在 BSD 世界(例如 macOS)中,-I它们-J将多“行”传递给命令的方式有所不同。例子:

$ ls
file1 file2 file3

$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3

$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3

因此,对于-I, xargs 将为单独传递给它的每个元素运行命令。使用 时-J, xargs 将执行一次命令并连接所有元素并将它们作为参数传递在一起。

某些命令(例如rm或 )mkdir可以采用多个参数并对其进行操作,就像传递单个参数并多次运行它们一样。但某些应用程序可能会发生变化,具体取决于您向它们传递参数的方式。例如tar.您可以创建一个 tar 文件,然后向其中添加文件,也可以通过一次性向其中添加所有文件来创建 tar 文件。

$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %

答案2

如果这是-JBSD 版本的标志,xargs我不相信 GNU 有完全相同的选项xargs-J替换单个出现的复制字符串(例如%)每行都通过标准输入进入。 GNU 版本有一个相似的不过,选项:-I1。但是,您可以使用复制字符串多次使用该标志。

对于是否有一个或多个命令调用并不重要的用例,您应该能够使用 GNUxargs -I作为直接替代品。但你的示例使用了rsync,我确信你不希望多次调用它。

那么,您最好的做法就是考虑从 和find-exec操作开始的替代方案-execdir。这有两种变体。一种类似于 GNU -I,另一种类似于 BSD -J。看看这些例子……

# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt

现在将其与此进行比较:

$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt

两者之间的唯一区别是哪个“修饰符”出现在末尾,+或者;

1更令人困惑的是 BSD 版本也有,-I而且它的功能-J与 GNU相似-I!但这-I会受到其他标志的影响,并且很可能不是您正在寻找的。

相关内容