GoでCSVファイルを処理するCLIのツール(csvt)を作りました

スポンサーリンク

CSVファイルを処理するcsvtというCLIのツールをGoで作りました。
作り始める時点で用意しようと思っていた機能が揃ったので紹介します。

下記のようなサブコマンドを用意しています。

  • choose CSVファイル内から一部の列を取り出して新しいCSVファイルを作成する
  • count CSVファイルの行をカウントする
  • filter CSVファイルの行を条件に応じてフィルタリングし、新しいCSVファイルを作成する
  • header CSVファイルのヘッダ内容を表示する
  • join 2つのCSVファイルを列の値をキーとして結合する
  • remove CSVファイル内から一部の列を削除して新しいCSVファイルを作成する

一番気に入っているコマンドはjoinです。
ExcelのVOOKUP的なことができます。

$ csvt join -1 INPUT1 -2 INPUT2 -c COLUMN -o OUTPUT
Usage:
  csvt join [flags]

Flags:
  -1, --first string     First CSV file path.
  -2, --second string    Second CSV file path.
  -c, --column string    Name of the column to use for joining.
      --column2 string   (optional) Name of the column to use for joining in the second CSV file. Specify if different from the first CSV file.
  -o, --output string    Output CSV file path.
      --usingfile        (optional) Use temporary files for joining. Use this when joining large files that will not fit in memory.
      --norecord         (optional) No error even if there is no record corresponding to sencod CSV.
  -h, --help             help for join

例えば、input1.csvとして下記内容のCSVファイルと、

UserID,Name,Age,CompanyID
1,"Taro, Yamada",10,2
2,Hanako,21,1
3,Smith,30,2
4,Jun,22,4

input2.csvとして下記内容のCSVファイルを用意して、

CompanyID,CompanyName
1,CompanyA
2,CompanyB
3,CompanyC
4,"AAA Inc"

CompanyIDの値を使って結合します。

$ csvt join -1 input1.csv -2 input2.csv -c CompanyID -o output.csv

できあがったoutput.csvは下記のような内容になります。
input1.csvを基準として、input2.csvの内容を足していくようなイメージです。

UserID,Name,Age,CompanyID,CompanyName
1,"Taro, Yamada",10,2,CompanyB
2,Hanako,21,1,CompanyA
3,Smith,30,2,CompanyB
4,Jun,22,4,AAA Inc

--usingfile というオプションを利用すると、メモリにファイル全体を載せることなく結合するので、どんな大きなファイルでも問題なく処理できます。(数GBのCSVファイルでも使用メモリは数十MB)

他のコマンドも含め、詳しい利用方法はREADMEをご参照ください。

使っているもの

サブコマンドの仕組みは Cobra を使いました。とても簡単にサブコマンドが作れます。

joinコマンドでのメモリを使わない実装では、キーバリューストアのBoltを使いました。手軽に使えてすばらしいです。