LoginSignup
0
0

More than 5 years have passed since last update.

zaimのカンマ区切りのCSVをタブ区切りのCSVに変換する

Last updated at Posted at 2018-06-25

CSVというのは単一の仕様というのはどうやら無いらしく(RFC4180というのはあるがこれはカテゴリがInformationalなので、標準ではない)、データを吐く側と食う側でどのみち合意が必要なようです。
逆に合意さえあれば、パースを簡略化できます。
そんなわけでzaimのCSVの仕様を調べます。

zaimのCSVの仕様

タブの扱い

pbcopy(macOSのコマンドです)でタブ文字をクリップボードにコピーして、zaim web からタブ文字を含む取引を登録してみました。

$ printf '\t' | pbcopy

CSVをダウンロードしてみると、タブ文字はそのまま含まれていました。

改行の扱い

zaim Web からは改行文字の入力ができなかったので、アプリから入力してみました。
CSVをダウンロードしてみると、この取引のレコードは、改行がスペースに置き換えられていました。

awkで処理してみる

まず、タブを消す前処理です。

タブをスペース4つに置換するawkスクリプト
{
  sub("\t", "    ", $0);
  print $0
}

次に、カンマをタブに置換します。
単にtr ',' '\t'としてしまうと、ダブルクォートの中にカンマが出現する場合、フィールドの区切りがおかしくなってしまいます。
結構悩んだ挙げ句、以下のStackOverflowの回答にたどり着きました。

ダブルクォートでエスケープされているまずダブルクォートを区切り文字としてフィールドを分けてから、1フィールド飛ばしで ,\t に置換するとよいようです。
CSVにカンマが出現する場合、1フィールド中のカンマは必ず偶数個出現することを利用しているわけですね。

カンマ区切りのCSVをタブ区切りのCSVに変換するawkスクリプト
BEGIN {
  FS=OFS="\""
}
{
  for (i=1; i<=NF; i+=2) {
    gsub(/,/,"\t", $i);
  }
  print $0;
}

csvformat を使う

csvkitに含まれているcsvformatコマンドを使うともっと簡単にできます。

brew install csvkit
cat zaim.csv | csvformat -T
cat zaim.csv | csvformat -T | awk -v FS='\t' '{if(NF != 16){print NF}}'  # 各行のカラムの数を数えて正しくパースできていることを確認
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0