この記事は、ニフティグループ Advent Calendar 2021 21日目の記事です。
はじめに
皆さんはjqを活用していますでしょうか?
私は、業務の中でJSONデータを扱うことが多く、巨大なJSONデータの一部を抽出する時や整形して企画チームのメンバーに共有する時などにお世話になっております。
使うたびに、「そんなこと出来るの!?すげえ😂」と感動していました。
そこで、アドベントカレンダーの執筆を機会に「自分用のメモを作ってしまおう😚」と考え記事を書くことにしました。
使う頻度が高そうだと判断したもののみ抜粋しました。その点をご了承くださいませ。
環境
- macOS Catalina version 10.15.6
- jq version 1.6
以下の内容は公式ドキュメントを参考にしています。詳しく知りたい方はこちらを参考にしてください。
jq
インストール方法
brewで入れることができます。
$ brew install jq
macOS以外の方は以下のページを参考にしてください。
テスト用データ
以下のサンプルデータを使用します。
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
}
[
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
},
{
"name": "Suzuki",
"age": 30,
"address": {
"state": "chiba",
"city": "funabashi"
}
}
]
フォーマット
jqはデフォルトでJSONをフォーマットしてくれます。
以下の記述で、フォーマットのみを行います。
$ cat user.json | jq .
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
}
基本的な絞り込み
特定のキーの値のみ取得する
以下の記述で、特定のキーの値のみを取得できます。
ユーザのnameを取得してみます。
$ cat user.json | jq '.name'
"Tanaka"
複数のキーをドットで連結することにより、ネストされた値を取得することができます。
addressのstateを取得してみます。
$ cat user.json | jq '.address.state'
"tokyo"
配列についてはこの後解説しますが、要素ごとの値も取得することができます。
|
(パイプ)区切りにすることで、左側の処理から実行されます。
配列を取得した後に配列ごとにageを取得してみます。
$ cat users.json | jq '.[] | .age'
25
30
キーも残す場合は以下のように記述します。
$ cat users.json | jq '.[] | {name, age}'
{
"name": "Tanaka",
"age": 25
}
{
"name": "Suzuki",
"age": 30
}
複数のキーの値を取得する
条件がカンマで区切られている場合は、同じ入力が両方に行われそれぞれの結果が順番に出力されます。
今回であれば、
- ageを取得
- addressの中のstateを取得
の順番で処理されています。
$ cat user.json | jq '.age,.address.state'
25
"tokyo"
配列を取得する
以下の記述で、配列を取得できます。
全ユーザの情報を取得してみます。
$ cat users.json | jq '.[]'
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
}
{
"name": "Suzuki",
"age": 30,
"address": {
"state": "chiba",
"city": "funabashi"
}
}
配列の特定の要素のみ取得する
インデックスを指定することで、配列の一部を取得することができます。
2人目のユーザ情報のみ取得してみます。
$ cat users.json | jq '.[1]'
{
"name": "Suzuki",
"age": 30,
"address": {
"state": "chiba",
"city": "funabashi"
}
}
配列の構築
以下の記述で配列を構築できます。
ユーザごとのaddressを取得し、配列を構築してみます。
$ cat users.json | jq ['.[] | .address']
[
{
"state": "tokyo",
"city": "shinjuku"
},
{
"state": "chiba",
"city": "funabashi"
}
]
オブジェクトの構築
以下の記述でオブジェクトを構築できます。
ユーザごとのnameを取得し、namesというキーの値に設定してみます。
$ cat users.json | jq '{"names": [.[] | .name]}'
{
"names": [
"Tanaka",
"Suzuki"
]
}
計算
四則演算
四則演算は一通り実行できます。
ユーザの年齢に50加えてみます。
$ cat user.json | jq '.age+50'
75
配列の合計を取得する
配列に対して、 add関数
を使用することで合計値を取得することができます。
ageの合計を取得してみます。
$ cat users.json | jq '[.[] | .age] | add'
55
配列の平均を取得する
length関数については後で解説しますが、配列の長さで割ることで配列の平均を取得することができます。
ageの平均を取得してみます。
$ cat users.json | jq '[.[] | .age] | add / length'
27.5
その他の組み込み関数
長さを取得する
length関数
を使用することで、長さを取得することができます。配列の場合は要素数が取得できます。
ユーザの数を取得してみます。
$ cat users.json | jq '.| length'
2
キーの一覧を取得する
keys関数
を使用することで、オブジェクトのキーを一覧で取得できます。
$ cat user.json | jq 'keys'
[
"address",
"age",
"name"
]
特定のキーを削除する
del関数
を使用することで、キーの一部を削除することができます。
addressを削除してみます。
$ cat user.json | jq 'del(.address)'
{
"name": "Tanaka",
"age": 25
}
配列に適用することも可能です。
$ cat users.json | jq '.[] | del(.address)'
{
"name": "Tanaka",
"age": 25
}
{
"name": "Suzuki",
"age": 30
}
条件で絞り込んで取得する
select関数
を使用することで、条件で絞り込んで取得することができます。
ageが25のユーザのみ取得してみます。
$ cat users.json | jq '.[] | select(.age == 25)'
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
}
ソート
sort_by関数
を利用することで、特定の値をもとに昇順ソートできます。
ageをもとに昇順ソートしてみます。
$ cat users.json | jq 'sort_by(.age)'
[
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
},
{
"name": "Suzuki",
"age": 30,
"address": {
"state": "chiba",
"city": "funabashi"
}
}
]
降順ソートについては、 reverse関数
を使用することで実現できます。
$cat users.json | jq 'sort_by(.age) | reverse'
[
{
"name": "Suzuki",
"age": 30,
"address": {
"state": "chiba",
"city": "funabashi"
}
},
{
"name": "Tanaka",
"age": 25,
"address": {
"state": "tokyo",
"city": "shinjuku"
}
}
]
CSV化
@csv
を利用することで、jsonをcsvに変換することができます。
入力するjsonは配列である必要があります。
ユーザ情報をcsvとして取得してみます。
$ cat users.json | jq -r '.[] | [.name, .age, .address.state + " " + .address.city]| @csv'
"Tanaka",25,"tokyo shinjuku"
"Suzuki",30,"chiba funabashi"
最後に
今回はjqの使い方を学びました。エンジニアである以上、JSONとは切っても切り離せない関係です。
そんなJSONを効率よく扱う方法を学べたことは、自分にとって大きな財産になったと思います。
以上、閲覧していただきありがとうございました!!
皆さんのお気に入りの使い方がありましたら、ぜひコメントしていってください!