xargsを介して複数のパラメーターを渡す


17

xargsコマンドのさまざまな部分で複数のパラメーターを実行できるようにしたいのですが。

たとえば、次のとおりです。

echo {1..8} | xargs -n2 | xargs -I v1 -I v2 echo the number v1 comes before v2

それが戻ることを願っています

the number 1 comes before 2
the number 3 comes before 4 

...など

これは達成可能ですか?私の複数回の使用-Iは正しくないと思われます。

回答:


29

そんな風には使えないと思います-I。しかし、あなたが言うことによってあなたが望む効果/振る舞いを得ることができます:

echo {1..8} | xargs -n2 sh -c 'echo "the number $1 comes before $2"' sh

これにより、本質的に、を介して実行されるアドホックな 1行のシェルスクリプトが作成されます。入力から解析される2つの値は、この「スクリプト」に渡されます。シェルはそれらの値をおよびに割り当てます。これらは「スクリプト」で参照できます。xargssh -cxargs$1$2


4
ありがとうございました。私はshの男を読んでいますが、shへの2番目の呼び出しが何をするのか、ひいてはその省略が結果の「半分」をもたらす理由を理解するのに苦労しています。
Damien Sawyer

6
@DamienSawyerへの2回目の呼び出しはありませんshsh最後に続くのはに入れられるものです$0$0通常は、インタプリタまたはスクリプトの名前を保持します。
Kusalananda

私はそれが機能するトレーリングshを置き換えましたecho $sh。だから、最後のshプレースホルダとして機能
KENN

さて、それはクサラナンダが言ったことの単純化しすぎです。
スコット

6

の特定のケースではprintf、常に次のことができます。

echo {1..8} | xargs printf 'the number %s comes before %s\n'

なぜなら、1回の呼び出しに必要な数よりも多くの引数が与えられると、複数回実行するprintf組み込みのxargsような機能があるからです。それはほとんど利点がありませんが

printf 'the number %s comes before %s\n' {1..8}

また、大きなリストの場合、単純なxargsコマンドをxargs実行するとprintf、のいくつかのインスタンスが実行される可能性があり、その一部には奇数の引数がある場合があります。あなたは渡すことができます-n 1000xargs1000は到達しないように十分に小さいべきである偶数である場合、それを防ぐために引数リストが長すぎる制限と非常に多く実行しないように十分な大きさprintfsが。

xargsは、シェルのbuiltin printfではなく、external を呼び出すことに注意してくださいprintf。それぞれの呼び出しは、個別の新しいプロセスで行われます。

空の入力の場合、一部のBSDを除いprintfて、引数なしで1回実行されることにも注意してください。GNU xargsと互換性のあるものには、-r それ--no-run-if-emptyを回避する(または)オプションがあります。

明確にするために、この単純な答えはあなたのprintf例に固有であり、コマンドに一度に2つのパラメーターを渡す必要がある一般的なケースでは機能しません(diffたとえば、の場合)。の一般的な問題を解決するにはzsh、以下を使用できます。

for i j ({1..8}) echo "the number $i comes before $j"

(1)私見、上記のzsh部分は本当の答えです、そしてxargs-with-no-options部分はただの奇妙です。そのような場合、本当の答えを最初に考えることを検討します。(2)コマンドで引用符を使用しない理由があると思いますzsh。もしそうなら、あなたはそれを述べたいかもしれません、人々が上記を読んで引用符が重要ではないと考え始めないように。(または、傷つけないので、単にそれらを含めてください。)
スコット

これは本当にクールです。次の引数のコマンドラインに入力する必要がある引数をいくつ受け取るかを前もって確信が持てないような類似の場所を探して、ここに着陸しました。のような何かをしたawk -F'\t' '/match/{printf $1"\0"$2"\0"}' | xargs -0 printf -- '-args1 "%s" -args2 "%s"' | xargs mycommand
keithpjolley

@keithpjolley、より信頼性を高めるため-0の最初のの使用はxargs、2番目にそれを使用しないことによって打ち負かされます。また、printf(スタンドアロンユーティリティとawkprintf()関数の両方に対する)最初の引数は形式です。そこでは変数を使用しないでください。ここでは、あなたがすることができますawk -F'\t' '/match/{printf "-args1\0%s\0-args2\0%s\0", $1, $2}' | xargs -n400 -r0 mycommand。繰り返しに-n400なりますxargsが、4の倍数である引数の数を確実に渡す必要があります(すべてのawk実装\0がこのような使用をサポートしているわけではないことに注意してください)。
ステファンChazelas

-0より信頼性を高めるために使用しませんでした。私がやりたいことを実行させるために使用しました。
keithpjolley

2

これを試して:

echo {1..8} |xargs -n 2 bash -c 'echo "the number $0 comes before $1"'

2
これは、この場合には動作しますが、それは実行する方が良いでしょうsh -cとのスクリプトshで(または何を)$0。これがスクリプトで使用された場合、たとえばスクリプトが$0$@sh -cecho "the two numbers were $@"
Kusalananda
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.