整形されたJSON文字列を見たい時、minifyしたい時、jqコマンドがとても便利だったという話
昨日頑張って sed
をかじったため
sed -e '1,10s/\([}\]]\),/\1,\ /g' -e '1,10s/:{/&\ /g' -e '1,10s/e,/&,\ /g' test.json
みたいな涙ぐましい事してたんですが、検索してたら jq
ってコマンドで簡単にできるらしいです。
まずは単に整形する
例えばこんなminifyされたJSONがあったとして
{"photo":{"taken_at":1506609841,"created_at":1504609841,"title":"さっちゃん"}}
これをこうじゃ。
$ echo '{"photo":{"taken_at":1506609841,"created_at":1504609841,"title":"さっちゃん"}}' | jq . { "photo": { "taken_at": 1506609841, "created_at": 1504609841, "title": "さっちゃん" } }
この標準出力をファイルへリダイレクトする事で、整形されたJSON文字列をファイルへ書き込むこともできます。
必要な要素だけを取り出してみる
jqコマンドは .キー名
で、そのキーの要素だけを取り出して表示させることが可能です*1。
これを利用すると、
$ echo '{"photo":{"taken_at":1506609841,"created_at":1504609841,"title":"さっちゃん"}}' | jq .photo { "taken_at": 1506609841, "created_at": 1504609841, "title": "さっちゃん" } $ echo '{"photo":{"taken_at":1506609841,"created_at":1504609841,"title":"さっちゃん"}}' | jq .photo.title "さっちゃん"
といったことができます。
配列の中の指定した要素を列挙する
さらに、配列については以下のようなことも可能です。
こういうJSONがあったとして
// sample.json { "order" : { "items" : [ { "id": 1, "name": "野球ボール", "price": 1296, "count": 3 }, { "id": 2, "name": "野球バット", "price": 1600, "count": 1 } ] } }
$ cat sample.json | jq .order.items [ { "id": 1, "name": "野球ボール", "price": 1296, "count": 3 }, { "id": 2, "name": "野球バット", "price": 1600, "count": 1 } ] // []で出力から配列の[]をはぐ $ cat sample.json | jq .order.items[] { "id": 1, "name": "野球ボール", "price": 1296, "count": 3 } { "id": 2, "name": "野球バット", "price": 1600, "count": 1 } // [].キー名で配列の中の要素でそのキーだけを列挙する $ cat sample.json | jq .order.items[].name "野球ボール" "野球バット"
出力から "(ダブルクオート) をはぐ
列挙した要素を他のコマンドの入力にしたい場合など "
が邪魔な場合には -r
オプションではげます
cat sample.json | jq .order.items[].name -r 野球ボール 野球バット
パイプが利用できる
なんと、 jq
の中だけでもパイプを使うことができます。これによって複雑なJSONの整形、要素の抽出や簡単な集計処理が行えます。
$ cat sample.json | jq .order.items[].price | awk '{m+=$1} END{print m;}' 2896
minifyする
-c
オプションを利用することで、整形されているJSON文字列をminifyすることも可能です。
$ jq -c . < sample.json {"order":{"items":[{"id":1,"name":"野球ボール","price":1296,"count":3},{"id":2,"name":"野球バット","price":1600,"count":1}]}}
めっちゃ便利! 現場からは以上です。
なんか awk
もやらねばいけないような気がするけど、明日は簡易自作コマンドの話をする。
参考
- http://leetmikeal.hatenablog.com/entry/20130117/1358423717
- https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
- https://nelsonslog.wordpress.com/2016/08/19/using-jq-to-minify-json/
*1:先ほどの . は全体を表示する、という意味