ソース入力があります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
何か案が?
これまでに挙げた解決策はいずれも、スペースを含むファイル名を正しく処理しません。ファイル名に 'または "が含まれていると、失敗するものもあります。入力ファイルがユーザーによって生成された場合、驚くべきファイル名に備える必要があります。
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
それらのすべてを聞かないでください:)この例を見てください:
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
どうですか:
echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
echo my-program --file="$1" --file="$2" --file="$3"
' argv0
sed
を使用して各行の前に--file=
を付けてからxargs
を呼び出すことができます。
sed -e 's/^/--file=/' input.txt | xargs my-program
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#* }'
私は同様の問題に出くわし、これまでに提示されたものよりも優れたクリーンなソリューションを見つけました。
私が終了した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つの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
私はこの正確な問題の解決策を探していましたが、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
echo
が改行を出力するためです。のようなものを試してください
echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`
xargsはそのようには機能しません。試してください:
myprogram $(sed -e 's/^ /-file = /' input.txt)
ループからエコーアウトすることについてはまだ誰も言及していないので、完全を期すためにそれを入れます(2番目のアプローチで、sedが最初になります)。
for line in $(< input.txt) ; do echo --file=$line ; done | xargs echo my-program
実際、それは比較的簡単です:
... | 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値として修飾されていると仮定します)。