web-dev-qa-db-ja.com

複数の引数を持つxargs

ソース入力があります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

何か案が?

53
Howard

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

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

25
Ole Tange

それらのすべてを聞かないでください:)この例を見てください:

echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs

出力は

this is first:argument1 second:argument2 third:argument3
80
sauliux

どうですか:

echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
   echo my-program --file="$1" --file="$2" --file="$3"
' argv0
18
yabt

sedを使用して各行の前に--file=を付けてからxargsを呼び出すことができます。

sed -e 's/^/--file=/' input.txt | xargs my-program
6
Bart Sas

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#* }'
5
maharvey67

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

私が終了した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 null-separationを使用して、スペースまたはその他の有線名を持つファイルを適切に処理するようにします。

ただし、まだ深くテストしていないことに注意してください。動作しているようですが。

2
Adam Badura

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
2
jjo

私はこの正確な問題の解決策を探していましたが、midleのスクリプトをコーディングすることの結論に至りました。

次の例の標準出力を変換するには、-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の引数の間にスペースを入れる必要があります。または、スクリプト内で選択したデリミターが何であれ、スクリプト内で-f1および-f2見つかった最初のデリミタの位置に応じて、最初の単語を取得し、2番目の単語を取得します(デリミタは、 '' ';' '。'にすることができます。

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

乾杯!

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

1
HoNgOuRu

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

echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`
1
aioobe

xargsはそのようには機能しません。試してください:

 myprogram $(sed -e 's/^ /-file = /' input.txt)
1
Burton Samograd

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

for line in $(< input.txt) ; do echo --file=$line ; done | xargs echo my-program
0
conny

実際、それは比較的簡単です:

... | sed 's/^/--prefix=/g' | xargs echo | xargs -I PARAMS your_cmd PARAMS

sed 's/^/--prefix=/g'は、各パラメーターの前に--prefix =を付ける必要がある場合のオプションです。

xargs echoは、param行のリスト(各行に1つのparam)を単一行のparamsのリストに変換し、xargs -I PARAMS your_cmd PARAMSを使用すると、コマンドを実行して、必要な場所にパラメーターを配置できます。

そう cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMSは必要なことを行います(input.txt内のすべての行が単純で、それぞれが単一のparam値として修飾されていると仮定します)。

0