CSVファイルの状態を監査するgemを作った

Posted by jolantern on Sunday, May 17, 2020

背景

仕事でもプライベートで書いているコードの参照するデータでも、ちょくちょくCSVを使う。CSVのほうがいい理由は、雑に開いてコピペするだけでGoogle SpreadSheetにいい感じに貼り付けてくれるとか、エンジニアじゃなくても簡単に(簡単とは言っていない)編集できるとか…。そう、簡単ではない。でも、TSVを書くのにTabを入力するのにはどうしたらいいのかとかを非エンジニア職に教えるより、まあまあ馴染みのあるCSVのほうが良かったりする。見たら何で区切っているのかわかるし(スペースなのかタブ文字なのかなんて、わかんない人の方が実は大多数ではないだろうか)。

プライベートでも諸事情でCSVで書いていたりするし、直にSpreadSheetに書いていることも多々あるのだけど、そういうときでも重複した内容が書かれているとめんどくさい時がある。例えば下記のような感じ。

<td>
  engineer
</td>
<td>
  designer
</td>
<td>
  engineer
</td>

山田太郎が二人いる。こんな具合で、ライセンス管理台帳とか、株式の管理でなんか同じ銘柄が2行あってどっちが正しいんだよとかそういう事がある。いや、重複嫌とかならExcel使えよとかそういう話じゃないんだ。例えばこのCSVを元に自動でライセンスを割り当てたり、期限が来たらライセンスを剥ぎ取ったり、証券コードを元に何かを検索したりするんだよ。Excelだとやりづらいからやなんだよとか、そういう話(まあ証券コード管理するのはもうちょいマシな手段を使えばいいのだが)。

適当にググったらgo製の似た感じのツールはあるっぽかった。Ruby製のがほし〜となって調べたけどでてこなかったので書いた、という感じ。

作ったgem

これ。

j-o-lantern0422/csvcop: csv linter like rubocop

使い方は

configディレクトリを見ると色々書かれたyamlが出てくる。記法はなんとなく、rubocopを参考にしたのだけど実は機能しているのは DeplicatedElementInOneColumn だけです。そもそもCSVとして壊れているものなんかを検出したり、区切り文字に , を使うのか、1要素をダブルクオーテーションで囲うのかとか考えていると先に進まなかったので先に一番欲しかった重複した要素があったら教える、という機能を実装した。どういったものがCSVとして正しいのかはRFCを読まないとわからないのだろうけど、多分実際には「こうあってほしいCSV」を監査できるのが一番ニーズがあるんだろうな。

今後の予定

とりあえず、CSVとして壊れているものとか、1要素内に空白が存在することを許さないとか、このカラムの列において空の要素を許さないとか、そういう僕が欲しい機能から順番に実装していきたい。