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


111

長い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です。どうして?


7
あなたは考慮されているawk使用する$1$2など?
BeemerGuy 2010年

4
副注として:コマンド<<(echo "string")--->コマンド<<< "string"
tokland

1
'cut'コマンドラインプログラムはそのために設計されました:ss64.com/bash/cut.html
Jay

回答:


214

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

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

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


7
提案されたソリューションは、非常に単純なCSVファイル、つまりヘッダーと値にカンマと埋め込まれた引用符がない場合に適しています。汎用CSVパーサーを作成するのは実際には非常に困難です(特に、いくつかのCSV "標準"があるため)。CSVファイルを* nixツールに対応するための1つの方法は、Excelなどを使用して、CSVファイルをTSV(タブ区切り値)に変換することです。
ピーク

体の中でmkdirができないのは面白いですね。私は取得していますcommand not foundecho作品のみ。
Zsolt 2016年

1
@Zsolt:該当する理由はありません。入力ミスまたは印刷されていない文字が必要です。
追って通知があるまで一時停止。

2
@DennisWilliamsonセパレータを囲む必要があります。たとえば、次のものを使用する場合;while IFS=";" read col1 col2; do ...
thomas.mc.work

1
@ thomas.mc.work:シェルに特別なセミコロンやその他の文字の場合も同様です。コンマの場合は不要で、不要な文字は省略したい傾向があります。たとえば、中かっこ(例:)を使用して常に展開用の変数を指定できますが${var}、必要がない場合は省略します。私には、きれいに見えます。
追って通知があるまで一時停止。

10

manページから:

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

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


3

引用符で囲まれ、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
いいですね、コマ(、)も使用できます
pkarc

0

いくつかの行でCSVファイルを読みたいなら、これが解決策です。

while IFS=, read -ra line
do 
    test $i -eq 1 && ((i=i+1)) && continue
    for col_val in ${line[@]}
    do
        echo -n "$col_val|"                 
    done
    echo        
done < "$csvFile"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.