データ交換のフォーマットとして至る所で使われる JSON ですが、データを整形して見やすくしたいことはよくあることです。
例えば、以下のような感じでデータをもらっても、パッと見よくわかりません。
[{"id":1,"name":"Leanne Graham","username":"Bret","email":"Sincere@april.biz","address":{"street":"Kulas Light","zipcode":"92998-3874"},"phone":"1-770-736-8031 x56442","company":{"name":"Romaguera-Crona"}}]
整形してあげると以下のように読みやすくなります。
[ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere@april.biz", "address": { "street": "Kulas Light", "zipcode": "92998-3874" }, "phone": "1-770-736-8031 x56442", "company": { "name": "Romaguera-Crona" } } ]
このような整形を行ってくれるツールはいろいろとあります。IDE など使っていたら、IDE に整形機能が通常バンドルされているのではないでしょうか。
ここでは、Emacs を使っている場合にサクッと整形する方法を記載します。
ところで・・・最近 Emacs 使いの影が薄くなっているような気がします。。大部分の方が Vim 使いになってしまっているのでしょうか。
(いや、最近の若い子はそもそもEmacs/Viなど好き好んで使っていないのかもしれませんね。。)
jq コマンド便利です
まずは、整形はもちろん、値の列挙、フィルタリングなどもできる便利なコマンド jq
です。
Tutorial、jq コマンドを使う日常のご紹介 - Qiita などのページを見ていただくと使い方、使いこなし方が把握できるのではないかと思います。
先程の整形されていないデータを jq コマンドを使って整形します。
$ echo '[{"id":1,"name":"Leanne Graham","username":"Bret","email":"Sincere@april.biz","address":{"street":"Kulas Light","zipcode":"92998-3874"},"phone":"1-770-736-8031 x56442","company":{"name":"Romaguera-Crona"}}]' | jq . [ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere@april.biz", "address": { "street": "Kulas Light", "zipcode": "92998-3874" }, "phone": "1-770-736-8031 x56442", "company": { "name": "Romaguera-Crona" } } ]
パイプ(|
)を使って jq
にデータを流し込んでいるだけですね。サクッと整形できました。
Emacs を使って JSON データを整形
次に、Emacs の標準パッケージを使う方法と、上記で使った外部コマンド(jq
)を使うケースと2つ記載します。
標準で組み込まれている json-pretty-print-buffer
/json-pretty-print
を使う
Emacs 24.4 (だと思います)以降であれば、標準で JSON の整形ツールが使えます。(標準elispの中にあるjson.el
で定義されています)
json-pretty-print-buffer
とjson-pretty-print
があり、その名の通り、buffer付きはバッファ内のものを対象として、無しの方はリージョンを対象とします。
先程使った非整形の JSON データをファイルに保存し、Emacs で開いている状態です。
この状態で M-x json-pretty-print-buffer
しますと、
素晴らしいです。
Emacs から外部コマンド jq
を使う
整形だけあれば、標準機能で十分ですね。外部コマンド jq
を使う目的としては、jq
の持っている整形以外の機能(値の列挙、フィルターなど)も使える点になります。
Emacs で表示しているデータを外部コマンドに流し込むには、M-!
(shell-command-on-region
) が使えます。M-!
を使うことで、リージョンのデータを標準入力として指定したコマンド(ここではjq
)に流し込むことができるのです。
また、M-!
だけで実行するとその実行結果は別バッファに出力されますが、C-u
(universal-argument
) という前置引数を与えることのできるコマンドを入れることで、カレントバッファーにそのまま結果を挿入することができます。
やってみましょう。まずは、C-x h
(mark-whole-buffer
) でバッファの全てのデータをリージョンにしています。
この状態で、C-u
をタイプし、続けて、M-!
をタイプします。下部のコマンドバッファに"Shell command on region: "と来ますので、上述していた jq
コマンドをそのまま入力します(jq .
)。
素晴らしいです。カレントバッファがそのまま整形されました。
jq
は普通のコマンドとして使えますので、使える機能を使っていきます。
例えば、データ内のname
の部分だけ抽出したいとします。また、結果のダブルクォーテーションは外したいとします。
これはコマンドラインでjq -r ".[].name"
とやればできます。これをそのまま Emacs でも使えます。
手順は先程と同じで、”Shell command"で入力しているコマンドだけが違います。
ちゃんと name の値だけが抽出されました。配列の要素が1個だけですので、結果も1つです。
(実際のところ、このケースの場合、別のバッファに出力した方がいいでしょうね。。)
標準機能を使わずに外部コマンド jq
を使うメリットはこのように、jq
のフル機能が使えるところです。とても便利です。
以上です。