伝統的なUNIX/Linuxのコマンドラインツールは行単位の処理が得意ですが、その一方でより複雑なデータ構造の取り扱いを比較的苦手としています。
そのため、JSONの取り扱いには、jqのような専用ツールを使ったり、あるいは何らかのプログラミング言語のJSONパーサで処理をすることが多いかと思います。
でもjqって記法難しいし……そもそも今は中身をgrepしたいだけなのに……JSONがフラットな行形式だったらいいのに……そんな無茶な願いを叶えるツールが**gron**です。
※ gronのドキュメントはとても簡潔なので、英語が苦でない人は、この記事よりも本家のREADMEを読むことを推奨します。
インストール
Macならbrewで入れられます。
brew install gron
Golangで書かれた所謂シングルバイナリなので、go getや、あるいは直接バイナリをPATHの通った場所に置いても構わないと思います。
# go getでインストールする場合
go get -u github.com/tomnomnom/gron
使い方
gronの標準入力にJSONを渡すと、"greppableな"形式1で出力されます。
$ echo '{"a": "aaa", "b": 101, "c": {"ca": true, "cb": false}}' | gron
json = {};
json.a = "aaa";
json.b = 101;
json.c = {};
json.c.ca = true;
json.c.cb = false;
この形式はgron -u
によってungron、つまり元のJSONに戻せます。
$ echo '{"a": "aaa", "b": 101, "c": {"ca": true, "cb": false}}' | gron | gron -u
{
"a": "aaa",
"b": 101,
"c": {
"ca": true,
"cb": false
}
}
gron形式は、grepなど他のコマンドで操作しやすいです。
$ echo '{"a": "aaa", "b": 101, "c": {"ca": true, "cb": false}}' | gron | fgrep 'c.ca'
json.c.ca = true;
もちろんgrep後にungronするなどの処理も自由自在にできます。
gronにはコマンドライン引数によるファイルからの読み取りのほか、URLを直接渡すこともできます。
gron 'http://jsonplaceholder.typicode.com/comments/1'
json = {};
json.body = "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium";
json.email = "Eliseo@gardner.biz";
json.id = 1;
json.name = "id labore ex et quam laborum";
json.postId = 1;
$ curl -s 'http://jsonplaceholder.typicode.com/comments/1' > tmp.json && gron tmp.json
json = {};
json.body = "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium";
json.email = "Eliseo@gardner.biz";
json.id = 1;
json.name = "id labore ex et quam laborum";
json.postId = 1;
ちなみに面白い性質として、gron形式はJavaScriptコードとしても解釈できます。そのため、例えばgrep加工した後のgron形式をJavaScript処理系で読み取ってevalする、といった処理も可能です。
まとめ
gronは高機能というわけではないのですが、さっと使えて必要な問題が解ける、手触りがとても良いツールです。
プログラマの道具箱に入っててもいいようなツールだなーと以前から思っていたのですが、意外にもQiitaに紹介記事がなさそうだったので書いてみました。
-
ちなみに、gron形式はちゃんと形式的な定義があるっぽいので、なんとなく安心感があります。参考: https://github.com/tomnomnom/gron/blob/v0.6.0/ungron.go#L4-L11 ↩