jqコマンドとは
-
JSONから必要なデータを抜き出したり、集計・整形して表示できるコマンド
-
sed, awk, grep みたいな使い方ができる
私はよくAPIやログから必要な箇所の抽出・整形に使ったりします。
使い方:単一オブジェクト
練習用のJSONデータが記述されたobject.jsonというファイルを元に説明していきます。
$ cat object.json
{
"id": 1,
"name": "Taro",
"age": 20,
"contact": {
"tel": "123-456",
"mobile": "090-xxxx-xxx"
},
"division": "Develop"
}
整形して表示
$ cat object.json | jq .
{
"id": 1,
"name": "Taro",
"age": 20,
"contact": {
"tel": "123-456",
"mobile": "090-xxxx-xxx"
},
"division": "Develop"
}
jqのあとに指定してあるドットはルートオブジェクトを指しており、JSONデータ全体を指定しています。
もともとのデータが整形されていたので分かりづらいですが、元のデータが1行で記載されているようなデータでも整形して表示してくれます。
指定したキー項目を抽出
ドットのあとにキー名を指定することで値を取得できます。
目的のデータがネストした中にある場合はキーをドットで連結すればOKです。
$ cat object.json | jq .id
1
$ cat object.json | jq .contact.tel
"123-456"
文字列の場合ダブルクォートも出力されてしまうので、パイプでつないで別の処理をするには都合が悪い場合があります。
そのときは-rのオプションをつけることでダブルクォートなしで出力できます。
$ cat object.json | jq -r .contact.tel
123-456
複数のキー項目を抽出
複数のキー項目を抽出したい場合はキーの指定部分をシングルクォートで囲んで、キーをカンマ区切りで指定します。
その際に[]で囲うことで配列として出力することも可能です。
$ cat object.json | jq -r '.id, .name'
1
Taro
$ cat object.json | jq '[.id, .name]'
[
1,
"Taro"
]
上記の場合だと複数行表示で都合が悪かったりします。
その場合は-cオプションをつけるか,加工したデータをパイプで@csvに渡せば1行で表示できます。
@csvはjqコマンドに用意されている機能です
// -cオプション
% cat object.json | jq -c '[.id, .name]'
[1,"Taro"]
// @csv
% cat object.json | jq -r '[.id, .name] | @csv'
1,"Taro"
// -r を付けずに@csvに渡すとダブルクォートがエスケープされて出力されます。
$ cat object.json | jq '[.id, .name] | @csv'
"1,\"Taro\""
使い方:配列
複数オブジェクトを含んだ配列を扱う場合について説明します。
次の練習用のJSONデータが記述されたarray.jsonというファイルを元に説明していきます。
[
{
"id": 1,
"name": "Taro",
"age": 20,
"contact": {
"tel": "123-456",
"mobile": "090-xxxx-xxx"
},
"division": "Develop"
},
{
"id": 2,
"name": "Jiro",
"age": 30,
"contact": {
"tel": "123-4567",
"mobile": "080=xxxx-xxx"
},
"division": "Human Resource"
},
{
"id": 3,
"name": "Saburo",
"age": 33,
"contact": {
"tel": "123-456",
"mobile": "070=xxxx-xxx"
},
"division": "Develop"
}
]
指定したキー項目を抽出
配列を扱う場合は.[]で中身のオブジェクトを取り出し、パイプで次のフィルタ処理に渡します。
$ cat array.json | jq '.[] | .id'
1
2
3
複数キー抽出する場合は先の単一オブジェクトと同様です
$ cat array.json | jq -r '.[] | [.id , .name] | @csv'
1,"Taro"
2,"Jiro"
3,"Saburo"
抽出条件の指定(select)
抽出条件を指定したい場合はselectを使います
完全一致検索
$ cat array.json | jq '.[] | select(.name == "Jiro")'
{
"id": 2,
"name": "Jiro",
"age": 30,
"contact": {
"tel": "123-4567",
"mobile": "080=xxxx-xxx"
},
"division": "Human Resource"
}
部分一致検索
$ cat array.json | jq '.[] | select(.name | contains("Ta"))'
{
"id": 1,
"name": "Taro",
"age": 20,
"contact": {
"tel": "123-456",
"mobile": "090=xxxx-xxx"
},
"division": "Develop"
}