web-dev-qa-db-ja.com

BashでCSVファイルを解析する方法は?

私は長いBashスクリプトに取り組んでいます。 CSVファイルからセルをBash変数に読み取りたい。行と最初の列を解析できますが、他の列は解析できません。これまでの私のコードは次のとおりです。


  cat myfile.csv|while read line
  do
    read -d, col1 col2 < <(echo $line)
    echo "I got:$col1|$col2"
  done

最初の列のみを印刷しています。追加のテストとして、次のことを試しました。

read -d, x y < <(echo a,b,)

そして、$ yは空です。だから私は試しました:

read x y < <(echo a b)

そして、$ yはbです。どうして?

90
User1

-dの代わりにIFSを使用する必要があります。

while IFS=, read -r col1 col2
do
    echo "I got:$col1|$col2"
done < myfile.csv

汎用CSV解析には、引用符で囲まれたフィールドを内部コンマで処理できる特殊なツールを使用する必要があることに注意してください。Bashだけでは処理できない問題もあります。このようなツールの例は、 cvstool および csvkit です。

177

manページから:

-d delim delimの最初の文字は、改行ではなく入力行を終了するために使用されます。

入力行をコンマで終了する-d,を使用しています。行の残りは読みません。そのため、$ yは空です。

9
dogbane

引用符で囲まれ、say |で区切られたcsvファイルを解析できます。次のコードで

while read -r line
do
    field1=$(echo $line | awk -F'|' '{printf "%s", $1}' | tr -d '"')
    field2=$(echo $line | awk -F'|' '{printf "%s", $2}' | tr -d '"')

    echo $field1 $field2
done < $csvFile

awkは文字列フィールドを変数に解析し、trは引用符を削除します。

各フィールドでawkが実行されるため、少し遅くなります。

1
Maithilish