xargs --max-args --replace をデフォルトの区切り文字として使用するときに発生する問題

xargs --max-args --replace をデフォルトの区切り文字として使用するときに発生する問題

これは期待どおりに機能します。

$ echo a b c | xargs --replace="{}" echo x "{}" y
x a b c y

これはまた働きます:

$ echo a b c | xargs --max-args=1 echo x
x a
x b
x c

しかし、期待どおりに動作しません。

$ echo a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a b c y

これでもない:

$ echo a b c | xargs --delimiter=' ' --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c
 y

次のような結果を期待しています。

x a y
x b y
x c y

回避策としてprintfと2つの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

なぜこれが起こるのかご存知ですか?

ベストアンサー1

~によるとPOSIX ドキュメントxargsスペースまたは改行で区切られた引数を使用して指定されたユーティリティを実行する必要があります。これは最初の2つの例で発生します。

ただし--replace、(or)を使用する場合は、改行文字のみ引数を区切ります。解決策は、パラメータを別々の行に提供することです-Ixargs

$ printf '%s\n' a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c y

POSIX オプションを使用します。

printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y

これにはxargs1行ではなく3行があります。 (max) 1行を取り、その行を引数として使用してユーティリティを実行します。

また、置換回数によって使用される引数の数が決まるため、上記-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

実際、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

xargsこれは、GNU coreutilsが実行するアクション(作成)とは異なりますx a b c y。これは、実装時にスペースが使用された-nにもかかわらず、パラメータ区切り文字として許可されるためです。したがって、と一緒に使用し-Iないでください(とにかく必要ありません)。-I-n

おすすめ記事