jqコマンド(jsonデータの加工, 整形)の使い方

jqコマンドは、JSONデータから目的の情報を抽出するのに便利な機能を提供しています。ここでは、jqコマンドの基本的な利用方法を確認します。

インストール

brew install jq
sudo yum -y install epel-release
sudo yum -y install jq
sudo apt -y update
sudo apt -y install jq

確認に利用するJSONデータ

ここでは、以下JSONデータを利用して動作確認を行います。

$ cat tmp.json 
{
  "total_count": 3,
  "items": [
    {
      "id": 111,
      "name": "aaa",
      "owner": {
        "id": 1111111,
        "type": "Organization"
      },
      "size": 10
    },
    {
      "id": 222,
      "name": "bbb",
      "owner": {
        "id": 2222222,
        "type": "User"
      },
      "size": 30
    },
    {
      "id": 333,
      "name": "ccc",
      "owner": {
        "id": 3333333,
        "type": "Organization"
      },
      "size": 25
    }
  ]
}

動作確認

起点から全て取得 & 整形

全JSONデータを取得するには . を利用します。

$ cat tmp.json | jq .
{
  "total_count": 3,
  "items": [
    {
      "id": 111,
      "name": "aaa",
      "owner": {
        "id": 1111111,
        "type": "Organization"
      },
      "size": 10
    },
    {
      "id": 222,
      "name": "bbb",
      "owner": {
        "id": 2222222,
        "type": "User"
      },
      "size": 30
    },
    {
      "id": 333,
      "name": "ccc",
      "owner": {
        "id": 3333333,
        "type": "Organization"
      },
      "size": 25
    }
  ]
}

このとき、以下のように見やすい形式に整形されます。curlで取得したJSONデータを整形したいときなどに、そのまま活用できます。

$ echo '{"xx": 123, "y": 234, "z": 345}' | jq .
{
  "xx": 123,
  "y": 234,
  "z": 345
}

逆に整形したくない場合、-cオプション を利用します

$ cat tmp.json | jq -c .
{"total_count":3,"items":[{"id":111,"name":"aaa","owner":{"id":1111111,"type":"Organization"},"size":10},{"id":222,"name":"bbb","owner":{"id":2222222,"type":"User"},"size":30},{"id":333,"name":"ccc","owner":{"id":3333333,"type":"Organization"},"size":25}]}

参考

特定要素取得

total_count の値を取得します。

$ cat tmp.json | jq .total_count
3

配列内の特定要素取得

items配列 の全要素から、id の値を取得します。

$ cat tmp.json | jq .items[].id
111
222
333

items配列 の1番目の要素の id の値を取得します。

$ cat tmp.json | jq .items[0].id
111

配列の要素数取得

$ cat tmp.json | jq '[.items[]] | length'
3

ダブルクォートを取り除く

$ cat tmp.json | jq .items[].name
"aaa"
"bbb"
"ccc"

-rオプション を利用すると、ダブルクォートが取り除かれます。

$ cat tmp.json | jq -r .items[].name
aaa
bbb
ccc

mapで新しい配列を生成

$ cat tmp.json | jq -r '.items | map({ name: .name, owner_id: .owner.id })'
[
  {
    "name": "aaa",
    "owner_id": 1111111
  },
  {
    "name": "bbb",
    "owner_id": 2222222
  },
  {
    "name": "ccc",
    "owner_id": 3333333
  }
]

以下のようにしても、同様の結果を得ることができます。

$ cat tmp.json | jq -r '[.items[] | { name: .name, owner_id: .owner.id }]'
[
  {
    "name": "aaa",
    "owner_id": 1111111
  },
  {
    "name": "bbb",
    "owner_id": 2222222
  },
  {
    "name": "ccc",
    "owner_id": 3333333
  }
]

集計

items配列各size の合計を求めます。

$ cat tmp.json | jq -r '[.items[].size] | add'
65

以下のようにしても、同様の結果を得ることができます。

$ cat tmp.json | jq 'reduce .items[] as $item (0; . + $item.size)'
65

絞り込み

items配列 から size の値が 25 より大きい要素を抽出します。

$ cat tmp.json | jq [.items[]] | jq 'map(select( .size > 25 ))'
[
  {
    "id": 222,
    "name": "bbb",
    "owner": {
      "id": 2222222,
      "type": "User"
    },
    "size": 30
  }
]

items配列 から owner.type の値が Organization である要素を抽出します。

$ cat tmp.json | jq [.items[]] | jq 'map(select( .owner.type == "Organization" ))'
[
  {
    "id": 111,
    "name": "aaa",
    "owner": {
      "id": 1111111,
      "type": "Organization"
    },
    "size": 10
  },
  {
    "id": 333,
    "name": "ccc",
    "owner": {
      "id": 3333333,
      "type": "Organization"
    },
    "size": 25
  }
]

CSV出力

@csv を利用して、CSV形式で出力します。

$ cat tmp.json | jq -r '.items[] | [.name, .owner.id] | @csv'
"aaa",1111111
"bbb",2222222
"ccc",3333333

参考