这个网站向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
如果这是-J
BSD 版本的标志,xargs
我不相信 GNU 有完全相同的选项xargs
。-J
替换单个出现的复制字符串(例如%
)每行都通过标准输入进入。 GNU 版本有一个相似的不过,选项:-I
1。但是,您可以使用复制字符串多次使用该标志。
对于是否有一个或多个命令调用并不重要的用例,您应该能够使用 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
会受到其他标志的影响,并且很可能不是您正在寻找的。