78

ソース入力、input.txtがあります

a.txt
b.txt
c.txt

これらの入力を次のようにプログラムにフィードしたいと思います。

my-program --file=a.txt --file=b.txt --file=c.txt

だから私はxargsを使おうとしますが、運がありません。

cat input.txt | xargs -i echo "my-program --file"{}

それは与えます

my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt

でも私はしたい

my-program --file=a.txt --file=b.txt --file=c.txt

何か案が?

4

13 に答える 13

38

これまでに提供された解決策は、スペースを含むファイル名を正しく処理していません。ファイル名に ' または " が含まれていると失敗するものさえあります。入力ファイルがユーザーによって生成された場合、驚くようなファイル名に備えておく必要があります。

GNU Parallelはこれらのファイル名を適切に処理し、(少なくとも) 3 つの異なるソリューションを提供します。プログラムが引数を 3 つしかとらない場合、これは機能します。

(echo a1.txt; echo b1.txt; echo c1.txt;
 echo a2.txt; echo b2.txt; echo c2.txt;) |
parallel -N 3 my-program --file={1} --file={2} --file={3}

または:

(echo a1.txt; echo b1.txt; echo c1.txt;
 echo a2.txt; echo b2.txt; echo c2.txt;) |
parallel -X -N 3 my-program --file={}

ただし、プログラムがコマンド ラインに収まる数の引数を取る場合は、次のようになります。

(echo a1.txt; echo b1.txt; echo c1.txt;
 echo d1.txt; echo e1.txt; echo f1.txt;) |
parallel -X my-program --file={}

詳細については、紹介ビデオをご覧ください: http://www.youtube.com/watch?v=OpaiGYxkSuQ

于 2010-09-25T18:49:35.173 に答える
22

どうですか:

echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
   echo my-program --file="$1" --file="$2" --file="$3"
' argv0
于 2010-09-22T16:20:40.057 に答える
8

2 つの xargs 呼び出しを使用すると、より簡単になります。1 番目は各行を に変換し--file=...、2 番目は実際に xargs を実行します ->

$ cat input.txt | xargs -I@ echo --file=@ | xargs echo my-program
my-program --file=a.txt --file=b.txt --file=c.txt
于 2018-04-20T21:52:06.263 に答える
7

を使用して各行sedにプレフィックスを付けてから、 :を呼び出すことができます。--file=xargs

sed -e 's/^/--file=/' input.txt | xargs my-program
于 2010-09-22T15:28:43.930 に答える
5

これは 3 つの引数に sed を使用するソリューションですが、各引数に同じ変換を適用するという制限があります。

cat input.txt | sed 's/^/--file=/g' | xargs -n3 my-program

2 つの引数に対して機能するメソッドを次に示しますが、より柔軟に使用できます。

cat input.txt | xargs -n 2 | xargs -I{} sh -c 'V="{}"; my-program -file=${V% *} -file=${V#* }'
于 2013-07-31T00:32:25.880 に答える
3

私は同様の問題に出くわし、これまでに提示されたものよりも優れたクリーンな解決策を見つけました。

xargs私が終了した構文は次のようになります(例として):

xargs -I X echo --file=X

完全なコマンドラインは次のとおりです。

my-program $(cat input.txt | xargs -I X echo --file=X)

のように動作します

my-program --file=a.txt --file=b.txt --file=c.txt

完了しました(提供input.txtには例のデータが含まれています)。


実際、私の場合、最初にファイルを見つける必要があり、それらをソートする必要があるため、コマンドラインは次のようになります。

my-program $(find base/path -name "some*pattern" -print0 | sort -z | xargs -0 -I X echo --files=X)

明確ではないかもしれないいくつかの詳細(それらは私のためではありませんでした):

  • some*patternそうしないと、シェルが に渡す前にそれを展開するためfindです。
  • -print0-z最後に-0ヌル区切りを使用して、スペースまたはその他のワイヤード名を含むファイルを適切に処理できるようにします。

ただし、まだ深くテストしていないことに注意してください。機能しているように見えますが。

于 2016-02-01T13:54:43.753 に答える
2

xargs はそのようには機能しません。試す:

  myprogram $(sed -e 's/^/--file=/' input.txt)
于 2010-09-22T16:16:57.620 に答える
1

この正確な問題の解決策を探していたところ、途中でスクリプトをコーディングするという結論に達しました。

次の例の標準出力を変換するには、-n '\n' 区切り文字を使用します

例:

 user@mybox:~$ echo "file1.txt file2.txt" | xargs -n1 ScriptInTheMiddle.sh

 inside the ScriptInTheMidle.sh:
 !#/bin/bash
 var1=`echo $1 | cut -d ' ' -f1 `
 var2=`echo $1 | cut -d ' ' -f2 `
 myprogram  "--file1="$var1 "--file2="$var2 

このソリューションを機能させるには、これらの引数 file1.txt と file2.txt の間にスペースを入れる必要があります。または、任意の区切り記号を選択する必要があります。もう 1 つ、スクリプト内で -f1 と -f2 を確認してください。見つかった最初の区切り文字の位置に応じて、最初の単語と 2 番目の単語を取得します (区切り文字は ' ' ';' '.' にすることができます。一重引用符で囲んだものは何でも構いません。必要な数のパラメーターを追加します。

xargs、cut、およびいくつかの bash スクリプトを使用して問題を解決しました。

乾杯!

あなたが通り過ぎたいなら、私はいくつかの役に立つヒントを持っていますhttp://hongouru.blogspot.com

于 2012-02-02T05:21:49.167 に答える
1

echo改行を出力するためです。次のようなものを試してください

echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`
于 2010-09-22T14:55:20.577 に答える
0

ループからエコーアウトすることについてはまだ誰も言及していないので、完全を期すためにそれを入れます(これは私の2番目のアプローチであり、sedが最初のアプローチです):

for line in $(< input.txt) ; do echo --file=$line ; done | xargs echo my-program
于 2014-12-23T09:00:10.537 に答える