ハラミTech

技術系ブログです

CSVやLTSVを表形式で出力するGo製のコマンド「Ruler」を作った

MySQLとかでSELECTしたとき、こういう出力されますよね。

mysql> SELECT * FROM products;
+-----------+-------------+-----------+----------+------------+
| productID | productCode | name      | quantity | price      |
+-----------+-------------+-----------+----------+------------+
|      1001 | PEN         | Pen Red   |     5000 |       1.23 |
|      1002 | PEN         | Pen Blue  |     8000 |       1.25 |
|      1003 | PEN         | Pen Black |     2000 |       1.25 |
|      1004 | PEC         | Pencil 2B |    10000 |       0.48 |
|      1005 | PEC         | Pencil 2H |     8000 |       0.49 |
|      1006 | PEC         | Pencil HB |        0 | 9999999.99 |
+-----------+-------------+-----------+----------+------------+

これコマンドラインでもやりたいなぁ…」と思ったんですよね。
でもそういうコマンド見当たらなかったので作ってみました

こういうことが出来ます。

$ cat hoge.csv
column1,column2,column3,column4
1,2,3,4
5,6,,7
8,,,9

$ cat hoge.csv | ruler
+---------+---------+---------+---------+
| column1 | column2 | column3 | column4 |
+---------+---------+---------+---------+
| 1       | 2       | 3       | 4       |
| 5       | 6       |         | 7       |
| 8       |         |         | 9       |
+---------+---------+---------+---------+

Ruler コマンドについて

こちらのコマンドはGitHubで公開しています。
https://github.com/morix1500/ruler

このコマンドで出来ることは以下の通りです。

  • CSV/TSV/LTSVの表作成
  • テキストの揃え位置の指定
  • ヘッダーレス指定

表作成

表を作成したいフォーマットを指定するといい感じに表にしてくれます。
CSVやTSVはわかりやすいと思いますが、「LTSV」も対応しました。
LTSVについてはこちらを参照してください。
http://d.hatena.ne.jp/naoya/20130209/1360381374

LTSVは一行一行にカラム名のようなもの(Label)が値の前方に配置されてます。
それをこんな感じで表示します。

$ cat hoge.log 
time:30/Nov/2016:00:55:08 +0900 host:xxx.xxx.xxx.xxx    forwardedfor:-  req:GET /v1/xxx HTTP/1.1        status:200
time:30/Nov/2016:00:56:37 +0900 host:xxx.xxx.xxx.xxx    forwardedfor:-  req:GET /v1/yyy HTTP/1.1        status:200  size:123

$ cat hoge.log | ruler -f ltsv
+----------------------------+-----------------+--------------+----------------------+--------+------+
| time                       | host            | forwardedfor | req                  | status | size |
+----------------------------+-----------------+--------------+----------------------+--------+------+
| 30/Nov/2016:00:55:08 +0900 | xxx.xxx.xxx.xxx | -            | GET /v1/xxx HTTP/1.1 | 200    |      |
| 30/Nov/2016:00:56:37 +0900 | xxx.xxx.xxx.xxx | -            | GET /v1/yyy HTTP/1.1 | 200    | 123  |
+----------------------------+-----------------+--------------+----------------------+--------+------+

Labelの増減があったりするので、それも対応しています。
このLTSVをCSVみたいな形式にするのはちょっと特殊なものだったのでライブラリ化しました。
https://github.com/morix1500/go-ltsv2tsv

対応する形式については、表形式にしやすいやつを選びました。
JSONは構造がネストになってると表形式で表せない場合があるので対応しませんでしたが、
アクセスログみたいな形式なら可能かもしれませんね。

テキストの揃え位置の指定

デフォルトだと左揃えですが、右揃えもできます。

$ cat hoge.csv | ruler -a right
+---------+---------+---------+---------+
| column1 | column2 | column3 | column4 |
+---------+---------+---------+---------+
|      1  |       2 |       3 |       4 |
|      5  |       6 |         |       7 |
|      8  |         |         |       9 |
+---------+---------+---------+---------+

ヘッダーレス指定

CSVは1行目にヘッダーがない場合がありますよね。
そんなときのオプションも用意してます。

$ cat hoge.csv
1,2,3,4
11,22,33,44
111,222,333,444

$ cat hoge.csv | ruler -n
+-----+-----+-----+-----+
| 1   | 2   | 3   | 4   |
| 11  | 22  | 33  | 44  |
| 111 | 222 | 333 | 444 |
+-----+-----+-----+-----+

LTSV形式の時にこのオプションを指定できるのですが、
データ行の1行目にLabelが表示されるので、LTSVの場合はあまり使わないかなぁと思ってます。

インストール方法

もし興味をお持ちになった方はバイナリをGitHubにアップロードしてるので
そちらからダウンロードお願いします~。
https://github.com/morix1500/ruler/releases

Rulerコマンドのユースケース

「このコマンド何に使うん?」って感じだと思いますが
自分はこんな感じで使うかな~と思ってます。

  • ログをいい感じにConfluenceとかに貼り付けたい
  • 非エンジニアの人に見やすいようにログを見せたい
  • CSVExcelなしで見やすくしたい

こう見ると主にログ関係ですね。

ログはエンジニアの人は慣れ親しんでるフォーマットなので、見るのは苦じゃないと思いますが
エンジニアじゃない人に見せるケースもたまにあるのでそういうとき、整形するのがめんどくさかったんですよね。 このコマンドのおかげでその辺楽になるなぁと思ってます。

今後対応したいこと

  • 新しい形式の対応
    • JSON
    • ほかなにかあれば
  • 中央揃え対応

対応したい機能はこんな感じです。

あと今回初めてまともにGolangを用いてツール作ったので
もうちょいいい感じの書き方ができたんじゃないかなというところばかりなので、
その辺も勉強してリファクタリングできたらなぁと思ってます。

参考文献

このコマンドを作るにあたって参考にした資料を記載しておきます。
本当に参考になりました、ありがとうございます!!!