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 はコマンドを 1 回実行し、すべての要素を連結して、それらをまとめて引数として渡します。

rmやなどの一部のコマンドは、mkdir複数の引数を受け取り、単一の引数を渡して複数回実行した場合と同じように動作します。ただし、一部のアプリでは、引数を渡す方法によって動作が変わる場合があります。たとえばtar、 の場合、tar ファイルを作成してからファイルを追加することも、一度にすべてのファイルを追加して tar ファイルを作成することもできます。

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

答え2

もしこれが-JBSD版のフラグであるならば、 GNUには全く同等のオプションがあるとxargsは思えませんxargs-J再配置(例%)各行は標準入力から入力されます。GNU版では似ているオプション:-I1。ただし、再配置そのフラグを複数回使用します。

xargs -Iコマンド呼び出しが 1 回か複数かは重要ではないユースケースでは、ドロップイン代替としてGNU を使用できるはずです。ただし、あなたの例では GNU を使用しておりrsync、その複数回の呼び出しは望ましくないはずです。

その場合、最善の行動は、find-execまたは-execdirアクションで始まる代替案を検討することです。これらには 2 つのバリエーションがあります。1 つは GNU に類似しており-I、もう 1 つは 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

2 つの違いは、最後にどの「修飾子」が現れる+かどうかだけです;

1さらに混乱を招くのは、BSD バージョンにも があり-I、その機能は-Jと GNUの両方に似ていることです-I。ただし、これは-I他のフラグの影響を受けるため、探しているものではない可能性が高くなります。

関連情報