はじめまして、湯尾(ゆお)と申します。
初投稿となりますので、簡単に自己紹介させていただきます。
経歴としては、10数年ほどRed Hat系Linuxの構築から運用監視を生業にしておりました。趣味は釣りで、社内の釣り部にも所属しております。今年も日焼けにやられて痛い目を見ています…
さて、早速ですが掲題のgronでjsonの扱いが楽になった、について。
まずはgronの紹介からはじめさせていただきます。
gronはgithubにて公開されているjsonをgrepしやすい形に置き換える(Make JSON greppable!)ツールです。
https://github.com/tomnomnom/gron
また、gronで変換した形式から、json形式に戻すこともできるため情報の切り出しにとても便利なツールとなっています。
インストールもとても簡単で、ダウンロードして解凍したファイルを使うだけ、となります。
ダウンロードしたファイルを解凍 -sh-4.2$ tar zxf gron-linux-386-0.5.2.tgz 解凍後のファイルの権限確認 -sh-4.2$ ls -lh gron -rwxr-xr-x 1 yuo Domain Users 5.8M Apr 4 19:15 gron 動作確認(バージョン情報表示) -sh-4.2$ ./gron --version gron version 0.5.2
あとは上記ファイルをパスが通っているディレクトリ(例:/usr/local/bin)に置くと、より一層便利にご利用いただけます。
さて、続いてはjsonの扱いが楽になった件、どんな点が楽になったかを下記のデータを例にして説明致します。
-sh-4.2$ cat test.txt [{"Server_A": {"customer": "AAA corp","role": "WEB"},"Server_B": {"customer": "BBB build","role": "e-mail"},"Server_C": {"customer": "CCC games","role": "gaming"},"Server_D": {"customer": "DDD corp","role": "WEB"},"Server_E": {"customer": "EEE corp","role": "e-mail"}}]
上記は成形前のデータとなります。とても人間が読みたくなる代物ではありません。また、grepやsed、awkなどのコマンドで必要な情報を取得するのも、とても難しい状態です。
次に、jqを使って可読性の高いフォーマットに成形したものが下記になります。
-sh-4.2$ cat test.txt | jq . [ { "Server_A": { "customer": "AAA corp", "role": "WEB" }, "Server_B": { "customer": "BBB build", "role": "e-mail" }, "Server_C": { "customer": "CCC games", "role": "gaming" }, "Server_D": { "customer": "DDD corp", "role": "WEB" }, "Server_E": { "customer": "EEE corp", "role": "e-mail" } } ]
改行とインデントが施されるだけで大幅に読みやすくなりました。
しかし、実際に特定の情報を取得しようとしたときに困るケースがあります。
例えば、上記のデータで「KeyがroleでValueがWEBのオブジェクトだけを取り出したい」となった場合、オブジェクトの配下にroleが置かれているため、まず各オブジェクト名を取得し、そのオブジェクトの中のroleをチェックするという形になると思います。
しかし、gronを通して見てみますと下記の様になります。
-sh-4.2$ cat test.txt | gron json = []; json[0] = {}; json[0].Server_A = {}; json[0].Server_A.customer = "AAA corp"; json[0].Server_A.role = "WEB"; json[0].Server_B = {}; json[0].Server_B.customer = "BBB build"; json[0].Server_B.role = "e-mail"; json[0].Server_C = {}; json[0].Server_C.customer = "CCC games"; json[0].Server_C.role = "gaming"; json[0].Server_D = {}; json[0].Server_D.customer = "DDD corp"; json[0].Server_D.role = "WEB"; json[0].Server_E = {}; json[0].Server_E.customer = "EEE corp"; json[0].Server_E.role = "e-mail";
人間には若干読みにくい形式ではありますが、Valueごとに配列やオブジェクトを1行の階層構造の様にまとめて表記しています。
さて、本題ですが、本家README で宣言されている Make JSON greppable! の言葉通り、gronを通したデータはgrepしやすい形式になっております。極端に言えば、role が WEB である情報だけを取得したい場合は下記の様にするだけでOKです。
-sh-4.2$ cat test.txt | gron |grep WEB json[0].Server_A.role = "WEB"; json[0].Server_D.role = "WEB";
grepした結果を再度json形式に戻したい場合は次の様にして簡単に戻せます。
-sh-4.2$ cat test.txt | gron |grep WEB | gron --ungron [ { "Server_A": { "role": "WEB" }, "Server_D": { "role": "WEB" } } ]
また、1行にValueまでの情報がまとめられていますので、grepした結果をsedやawkを使って自由に成形できる、というのも(お行儀悪いかもですが)個人的には大変助かっております。
APIを使って取得したjson形式のデータを取り扱おう、とした時にgrepやsed、awkといったサーバエンジニアが普段使いするコマンドと相性が良いとは言えず、jqと繰り返し処理を駆使して必要な情報を取得する… という苦労をした方は少なくないと思います。そういった時に、gronを使えばいつもの調子で抽出や成形ができてしまいます。
本格的にjson形式のデータと向き合うのであれば各種parserを利用するのがベターな方法だとは思います。しかし、Linux操作の延長としてjson形式のデータを扱えるというのは、json形式でデータを提供してくれるAPIなどを扱うことへの障壁を1つ下げることができる、ということにつながるのではないでしょうか。
私的にではありますが「ひとまずやってみる」という気軽さを提供できるのが、gronの素晴らしいところだと感じています。
以上、最後までお読みいただきありがとうございました。
本ブログの情報につきましては、自社の検証に基づいた結果からの情報提供であり、
品質保証を目的としたものではございません。