web-dev-qa-db-ja.com

xargs-各引数にパラメーターを追加します

l="a b c"

echo $l | xargs ls

収量

ls a b c

どのコンストラクトが生成されるか

mycommand -f a -f b -f c
12
not-a-user

それを行う1つの方法:

echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand

これは、ab、およびcに空白、改行、引用符、またはバックスラッシュが含まれていないことを前提としています。 :)

GNU findutilを使用すると、一般的なケースを処理できますが、少し複雑です。

echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand

|セパレーターは、ab、またはcにない他の文字に置き換えることができます。

編集:@ MichaelMol のように、引数のリストが非常に長い場合、引数の最大長がオーバーフローするリスクがありますmycommandに渡すことができます。それが発生すると、最後のxargsがリストを分割してmycommandの別のコピーを実行し、終了していない-fが残るリスクがあります。そのような状況が心配な場合は、上記の最後のxargs -0を次のように置き換えることができます。

... | xargs -x -0 mycommand

これは問題を解決しませんが、引数のリストが長くなりすぎるとmycommandの実行を中止します。

13
Satō Katsura

これに対処するためのより良い方法(IMO)は次のとおりです。

  • zsh

    l=(a b c)
    mycommand -f$^l
    

    または、配列の圧縮を使用して、引数がオプションにアタッチされないようにします。

    l=(a b c) o=(-f)
    mycommand "${o:^^l}"
    

    このように、l配列に空の要素、またはスペースを含む要素、またはxargsのその他の問題のある文字が含まれている場合でも機能します。例:

    $ l=(a '' '"' 'x y' c) o=(-f)
    $ printf '<%s>\n' "${o:^^l}"
    <-f>
    <a>
    <-f>
    <>
    <-f>
    <">
    <-f>
    <x y>
    <-f>
    <c>
    
  • rc

    l=(a b c)
    mycommand -f$l
    
  • fish

    set l a b c
    mycommand -f$l
    

(AFAIK、rcおよびfishには配列の圧縮はありません)

bashのような古いスタイルのBourneのようなシェルを使用すると、いつでも実行できます($@配列の要素に任意の文字を許可します)。

set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
5