jqとは
jqはjsonから特定の値を抽出するのに超絶便利なコマンドラインツールです。テキスト処理を行えるCLIツールとしてはsedやawkなどいろいろとありますが、JSONの処理においてはjqの右に出るものは現状いないという認識です。 本記事では、問題を交えながら実践形式でjqの基本を抑えていきます。
インストール
Macユーザでjqコマンドのインストールがまだの方は以下の方法でインストールすることが可能です。 jqはその他のOSでも利用可能ですので、Mac以外のユーザは他サイトを参考にインストールしていただけたらなと思います。
brew install jq
brewコマンドを使えなくて失敗する方は先にHomebrewをインストールする必要があります。
以下のコマンドでjqコマンドが使えることを確認しましょう。
jq --version
基本的な使い方
jqは基本的に以下のようにcurlやcatを利用してjsonの出力し、パイプを利用してjqコマンドに流し込むといった利用方法になります。
cat sample.json | jq curl "http://localhost:7000" | jq
では早速問題を出します。
Q1 https://jsonplaceholder.typicode.com/photos をcurlで叩いて、jqで表示してみてください。 以下の「答えを見る」を押すとコマンドが表示されます。
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq
抽出
jqの利用方法で最も多いであろう、jsonデータからの値の抽出を見ていきます。
jqでは jq 'コマンド'
の形式でjsonから必要なデータのみを抽出することが可能です。
また、jq 'コマンド1 | コマンド2'
のようにパイプで繋げることで複数のコマンドを適用することもできます。
配列
https://jsonplaceholder.typicode.com/photos から帰ってくるデータは配列の中に複数の要素が含まれている形式になっていました。
配列の抽出では .[n]
を使ってn番目の要素をとったり、 .[n:m]
で n以上m未満の範囲をとってくることができます。
また、length
と指定すると要素の数を調べることができます。
以下の問題でも https://jsonplaceholder.typicode.com/photos を使って回答してください
Q2 0番目の要素のみを出力してください
# 期待される出力 { "albumId": 1, "id": 1, "title": "accusamus beatae ad facilis cum similique qui sunt", "url": "https://via.placeholder.com/600/92c952", "thumbnailUrl": "https://via.placeholder.com/150/92c952" }
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0]'
Q3 2番目から4番目までの要素のみを出力してください
[ { "albumId": 1, "id": 3, "title": "officia porro iure quia iusto qui ipsa ut modi", "url": "https://via.placeholder.com/600/24f355", "thumbnailUrl": "https://via.placeholder.com/150/24f355" }, { "albumId": 1, "id": 4, "title": "culpa odio esse rerum omnis laboriosam voluptate repudiandae", "url": "https://via.placeholder.com/600/d32776", "thumbnailUrl": "https://via.placeholder.com/150/d32776" }, { "albumId": 1, "id": 5, "title": "natus nisi omnis corporis facere molestiae rerum in", "url": "https://via.placeholder.com/600/f66b97", "thumbnailUrl": "https://via.placeholder.com/150/f66b97" } ]
答えを見る
.[n:m]
で指定した時、m番目の要素は含まないことに注意してください。
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[2:5]'
Q4 配列の要素数を出力してください。
# 期待される出力 5000
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq 'length'
キーによる抽出
キーに対応する値を求める時には.キー
という形式が利用できます。
また、複数の値を出したい場合は、カンマ(,)を使って.キー1,.キー2
のように表現することができます。
配列要素から取得する場合はjq '.[n].key'
のような指定が可能です。もしくは、パイプを利用して、jq 'コマンド1 | コマンド2'
のようにすることもできます。
Q5 0番目の要素のtitleを出力してください。
# 期待される出力 "accusamus beatae ad facilis cum similique qui sunt"
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0].title' # パイプを利用した別解 curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0] | .title'
Q6 0番目の要素のtitleだけでなく、idとalbumIdも同時に出力してください。
# 期待される出力 "accusamus beatae ad facilis cum similique qui sunt" 1 1
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0].title,.[0].id,.[0].albumId' # パイプを利用した別解 curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0] | .title,.id,.albumId'
Q6ではidとalbumIdのどちらも整数値なので、出力結果をみた時にどちらがidでどちらがalbumIdなのかわかりにくいですよね。 キーとバリューを含んだJSON形式で出力するには中括弧({})を利用します。
以下はその例です。
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0] | {id: .id, albumId: .albumId}' # 出力 { "id": 1, "albumId": 1 }
また、同じ要領で角括弧([])を使って配列を作ることもできます。
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0] | [.id, .albumId]' # 出力 [ 1, 1 ]
Q7 0番目の要素のタイトルとurlから構成されるJSONを出力してみてください。
# 期待される出力 { "title": "accusamus beatae ad facilis cum similique qui sunt", "url": "https://via.placeholder.com/600/92c952" }
答えを見る
curl "https://jsonplaceholder.typicode.com/photos" | jq '.[0] | {title: .title, url: .url}'
配列に対する便利関数
ここからの問題では以下の内容のsample.jsonを使います。
[ { "id": 1, "name": "Alice", "age": 30 }, { "id": 2, "name": "Bob", "age": 25 }, { "id": 3, "name": "Charlie", "age": 35 } ]
配列に対してはサイズを取得するlength
の他に、最大最小を求めるmax
やmin
、並びを変えるsort
など使いこなせると便利な機能がたくさんあります。
今回はサンプルとして配列サイズ小さなjsonファイルを利用していますが、大きなjsonファイルを扱う時にはかなり強力です。
また、map(.key)
を利用すると、配列の要素を絞り込むことができます。
Q9 それぞれの要素の年齢のみを配列として抽出してください
# 期待される出力 [ 30, 25, 35 ]
答えを見る
cat sample.json | jq 'map(.age)'
Q10 最も高い年齢を出力してください。
# 期待される出力 35
答えを見る
cat sample.json | jq 'map(.age) | max'
max_by(.key)
やmin_by(.key)
を利用するとあるフィールドの最大値、最小値をもつオブジェクトを検索して出力することができます。
Q11 最も若い人の名前を表示してください。
# 期待される出力 "Bob"
答えを見る
cat sample.json | jq 'min_by(.age).name'
まだまだいろいろあるんですがここまでにします。もっとたくさんの機能を知るには以下の記事がおすすめです。
参考: