コマンドの引数としてbashで区切られたテキストファイルを解析する


10

テキストファイルを次のように分割しています。

field1,field2,field3 
xield1,xield2,xield3 
dield1,dield2,dield3 
gield1,gield2,gield3

これらの各列はプログラムのパラメーターになります。プログラムは各行で呼び出されます

私はループのようなものを望んでいました:

for $i in file
    command $field2 -x $field3 -PN -$field1 >> output
done

このようなことをbashで達成するための最良の方法は何でしょうか?


フィールド数は一定ですか?
Joseph R.

@JosephR。はい、そうです、常に3
ディーン

回答:


7
while IFS=, read xx yy zz;do
    echo $xx $yy $zz
done < input_file

これは、フィールドの数が一定であれば機能するはずです。echoコマンドを使用する代わりに。


おかげで、私はこれを試してみましたが、最初の行でのみ機能するようです。コマンドが成功するとすぐに次のコマンドは試行されませんが、失敗した場合は次のコマンドが試行されます...
Dean

成功または失敗とはどういう意味ですか?あなたのコマンドは何をしますか?
coffeMug ​​2013

彼が実行しているコマンドは、「read」コマンドがそれに到達する前に標準入力を読み取っていると思います。
プラグウォッシュ

4

あなたが使用する必要があるwhilereadビルトイン:

while IFS= read -r line;do
    fields=($(printf "%s" "$line"|cut -d',' --output-delimiter=' ' -f1-))
    command "${fields[1]}" -x "${fields[2]}" ... # ${fields[1]} is field 2
done < your_file_here

この仕組み

  • cut声明は、ラインを取り、で指定された区切り文字にそれを分割します-d
  • --output-delimiter区切り文字であるcut我々は、配列の中に異なるフィールドを置くことができますので、ここで我々はスペースを選択し、選択したフィールドを表示するために使用されますfields
  • 最後に、すべてのフィールド(フィールド1から最後まで)が必要であり、ここでその-f1-役割を果たします。
  • これで、さまざまなフィールドが配列変数に格納されました。Bash fieldsでは配列のインデックスがゼロベースであるため、構文${field[number]}は必要な特定のフィールドにアクセスできますnumber

注意

  • フィールドのいずれかに空白が含まれている場合、これは失敗します。

一定数のフィールド

代わりに、1_CRの答えと同様のことを行うことができます

while IFS= read -r line;do
    IFS=, read -r field1 field2 field3 <<-EOI
    $line
    EOI
    command "$field2" -x "$field3" ... 
done < your_file_here

上記は、よりうるさいように見えますが、Bashだけでなく、POSIX準拠のシェルでも機能するはずです。


私が問題を抱えているファイルを読み込んでいるのではなく、行を列に分割しています。
ディーン

@ディーンうん、ごめんなさい。私は注意を払っていませんでした。今それに取り組んでいます。
Joseph R.

@Dean更新された回答をご覧ください。まもなく説明を追加します。
Joseph R.

@JosephR。、呼び出しでIFS適切な値に設定することにより、分割に外部ツールを使用しないようにすることができreadます
iruvar

@ 1_CRわかった、ありがとう。私はちょうどそれに到達していました:)
ジョセフR.

1

適切に設定することでread、各行を配列に分割できます。,IFS

while IFS=, read -r -a input; do
 printf "%s\n" "${input[0]}" "${input[1]}"
done < input.txt

したがって、上記の例では、0から始まるインデックスを使用して各配列要素にアクセスできます。


1

このawkワンライナーはあなたが望むことをします:

awk -F, '{cmd="echo " $2 " -x " $3 " -PN " $1 ">> output";  system(cmd)}' f.txt

echoコマンドとf.txt、繰り返し処理するファイルに置き換えます。

簡単な説明:区切り文字として-F,設定,されます。cmdコマンドを作成し、コマンドをsystem(cmd)呼び出します。


1

gnu sedも使用できます。

sed infile -e 's!^\([^,]*\),\([^,]*\),\([^,]*\)$!command \1 -x \2 -PN \3!e' >> output

sコマンドへのeオプションの使用に注意してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.