TECH

jqコマンドでjsonを操る!

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"
}

-TECH

© 2024 みひろぐ