jqコマンド覚え書き

2021年4月9日

jqコマンド

JSON から必要なものを取り出すときに使う jq コマンド。使い方をすぐ忘れてしまって毎回 jq Manual を見ているので、よく使うフィルタをメモしておきます。jq のバージョンは 1.6。随時更新。

目次

  1. サンプルの JSON 準備
  2. JSON をフォーマット
  3. 配列の中身をすべて取り出す
  4. 特定の配列の要素を取り出す
  5. キーを指定して値を取り出す
  6. 複数の値を取り出す
  7. ダブルクォーテーションを消す
  8. CSV 形式で出力する
  9. TSV 形式で出力する
  10. and/or 検索
  11. 正規表現で検索
  12. 文字列の結合

サンプルの JSON 準備

サンプルとして以下の JSON を使います。ターミナルで以下のコマンドを実行して $JSON という変数に入れておきます。

JSON=$(cat << EOS
[
  {
    "Address": "192.168.0.1",
    "ID": "1",
    "Name": "foo",
    "Version": "1.0.0",
    "Status": "ready"
  },
  {
      "Address": "192.168.0.2",
      "ID": "2",
      "Name": "bar",
      "Version": "1.0.1",
      "Status": "down"
  },
  {
      "Address": "192.168.0.3",
      "ID": "3",
      "Name": "buz",
      "Version": "2.0.0",
      "Status": "ready"
  }
]
EOS
)

JSON をフォーマット

一番単純なフィルタである . を使って JSON をフォーマットできます。改行やスペースが入っていなくて JSON が見づらい場合などに使えます。

例えばサンプルの JSON のスペースと改行を取り除くとこんな感じで見づらいですが

echo $JSON | tr -d '\n '
[{"Address":"192.168.0.1","ID":"1","Name":"foo","Version":"1.0.0","Status":"ready"}, ...

jq コマンドでJSON を再フォーマットするときれいな出力になります。

echo $JSON | tr -d '\n ' | jq '.'
[
  {
    "Address": "192.168.0.1",
    "ID": "1",
    "Name": "foo",
    "Version": "1.0.0",
    "Status": "ready"
  },
...

配列の中身をすべて取り出す

サンプルの JSON は全体が配列で囲まれています。.[]と指定することで配列の要素をすべて取り出すことができます。

echo $JSON | jq '.[]'
{
  "Address": "192.168.0.1",
  "ID": "1",
  "Name": "foo",
  "Version": "1.0.0",
  "Status": "ready"
}
{
  "Address": "192.168.0.2",
  "ID": "2",
  "Name": "bar",
  "Version": "1.0.1",
  "Status": "down"
}
...

特定の配列の要素を取り出す

.[0]のように配列の添字(インデックス)を指定すると、指定した配列の要素を取り出すことができます。

echo $JSON | jq '.[0]'
{
  "Address": "192.168.0.1",
  "ID": "1",
  "Name": "foo",
  "Version": "1.0.0",
  "Status": "ready"
}

キーを指定して値を取り出す

.Address のようにオブジェクトのキーを指定すると、値を取り出すことができます。

echo $JSON | jq '.[].Address'
"192.168.0.1"
"192.168.0.2"
"192.168.0.3"

複数の値を取り出す

キーをカンマで区切ると、複数の値を取り出すことができます。今回の例のように配列の中に複数のオブジェクトがある場合は、フィルタで先に配列の中身を取り出しパイプで繋ぐことで、出力結果が配列の要素ごとにまとまります。foreach 文のようなイメージです。

echo $JSON | jq '.[] | .Address, .ID'
"192.168.0.1"
"1"
"192.168.0.2"
"2"
"192.168.0.3"
"3"

ダブルクォーテーションを消す

jq で取得した結果を他の処理にわたす際にダブルクォーテーションが邪魔になることがあります。-r(--raw-output)オプションで消すことができます。

echo $JSON | jq -r '.[] | .Address, .ID'
192.168.0.1
1
192.168.0.2
2
192.168.0.3
3

CSV 形式で出力する

結果をパイプでつなぎ @csvとすることで、CSV 形式で出力することができます。@csv に渡す値は配列にする必要があります。ダブルクォーテーションが自動で付与されるため、-rオプションが必要です。

echo $JSON | jq -r '.[] | [.Address, .ID] | @csv'
"192.168.0.1","1"
"192.168.0.2","2"
"192.168.0.3","3"

TSV 形式で出力する

結果をパイプでつなぎ @tsvとすることで、TSV 形式で出力することができます。

echo $JSON | jq -r '.[] | [.Address, .ID] | @tsv'
192.168.0.1	1
192.168.0.2	2
192.168.0.3	3

絞り込み検索をする

select()関数を使うことで値の絞り込み検索ができます。たとえば Address が 192.168.0.1 のオブジェクトだけを出力したい場合は以下のようにします。

echo $JSON | jq -r '.[] | select(.Address == "192.168.0.1") | [.Address, .ID] | @tsv'
192.168.0.1	1

and/or 検索

select()の中で and/or のキーワードで検索条件の追加ができます。

and 検索

echo $JSON | jq -r '.[] | select(.Version == "2.0.0" and .Status == "ready") | [.Address, .ID, .Version, .Status] | @tsv'
192.168.0.3	3	2.0.0	ready

or 検索

echo $JSON | jq -r '.[] | select(.Address == "192.168.0.1" or .Address =="192.168.0.2") | [.Address, .ID] | @tsv'
192.168.0.1	1
192.168.0.2	2

正規表現で検索

select()の中で test()を使うと正規表現で検索ができます。

echo $JSON | jq -r '.[] | select(.Name | test("^b")) | [.Address, .ID, .Name] | @tsv'
192.168.0.2	2	bar
192.168.0.3	3	buz

文字列の結合

文字型に + を利用することで文字列の結合ができます。出力を加工したいときなどに使います。

echo $JSON | jq -r '.[] | [.Address + "/32", .ID] | @tsv'
192.168.0.1/32  1
192.168.0.2/32  2
192.168.0.3/32  3

-技術ブログ
-