csvファイルの単一行(インデックス付き)をzsh配列にインポートできますか?

csvファイルの単一行(インデックス付き)をzsh配列にインポートできますか?

zshでcsvファイルを1行ずつ解析し、コンマなしで配列に保存したいと思います。 zshから行を配列にインポートした後、次の行をインポートできますか?

問題は、大容量のcsvファイルを使用していますが、すべてのファイルをすばやくインポートできないことです。次のコードを試してみました。

arr_csv=() 
while IFS= read -r line 
do
    arr_csv+=("$line")
done < import.csv

ところで、ファイルが大きいので、1行を読んで保存(または1行にアクセス)したいと思います。

次のようにコードを変更できることを知っています。

arr_csv=() 
while IFS= read -r line 
do
    arr_csv=("$line")
    # some modifications
done < import.csv

しかし、ファイルを繰り返す場合は、csvファイルの行に対応するインデックスを使用できる場合は簡単になります。また、この方法は行を区切るコンマを削除しません。

答え1

私が言うことは、シェルではなくperl/ ... hereなどのCSVサポートを含む正しいプログラミング言語を使用する必要があるということです。python

ただし、zsh個々のセルで改行とキャリッジリターンを使用する必要があり、削除することを気にしない場合は、csvkitを使用してcsvをより簡単に処理できるcsvformat形式に再フォーマットできます。zshread

< file.csv csvformat -SU3 -P'\' |
  while IFS=, read -A array; do
    typeset array # or anything with $array
  done

たとえば、次のような入力の場合:

"foo bar ", "x,y", "blah""blah","new
line"
1,,2,"\\"

csvに関連する一般的な潜在的な落とし穴の例は次のとおりです。

array=( 'foo bar ' x,y 'blah"blah' newline )
array=( 1 '' 2 '\\' )

見つからない場合は-rエスケープ文字としてread認識されます。\残念ながらとしてエスケープされていますが、csvformat改行文字をエスケープするのではなく、行の連続として解釈されます。<newline>\<newline>read

入力にまったく表示されない2つの文字がわかっている場合は、それぞれフィールド区切り文字とレコード区切り文字として使用できます。たとえば、ASCIIです。記録区切り記号そして単位区切り記号これには制御文字が適切なようです。

us=$'\x1f' rs=$'\x1e'
< file.csv csvformat -SU3 -D$us -M$rs -Q$rs |
  while IFS=$us read -rd$rs -A array; do
    something with $array
  done

今回は同じ入力が与えられると次のようになります。

array=( 'foo bar ' x,y 'blah"blah' $'new\nline' )
array=( 1 '' 2 '\\' )

関連情報