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. 絞り込み検索をする
  11. and/or 検索
  12. 正規表現で検索
  13. 文字列の結合
  14. null 入力
  15. 集計
  16. 日付のフォーマット変更とタイムゾーン変更

サンプルの 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

null 入力

jq は通常、json データを読み込んで使いますが、-n (--null-input) オプションで読み込むデータが無くても動かすことができます。jq の機能をサッと試したいときに使えるテクニックです。

jq -n 'now|localtime|todate'
"2022-01-09T23:40:34Z"

集計

max, min, sum, count など集計について別の記事にまとめました。

jqコマンド
jqコマンドで集計 group by, max, sum, count

jq コマンドで集計(最大、合計、数、平均、並び替え)をする方法を紹介します。jq のバージョンは 1.6。 以前書いた jq コマンドの基本的な使い方の続きです。 サン...

続きを見る

日付のフォーマット変更とタイムゾーン変更

日付のフォーマット変更とタイムゾーン変更について別の記事にまとめました

jqコマンド
jqコマンドで日付のフォーマット変更とタイムゾーン変更

jq コマンドで日付を扱うときに、出力する日付のフォーマットを変更したり、タイムゾーンを UTC から JST に変更する機会があったので備忘録。jq Manual (Dates) に載っているコマ...

続きを見る

-技術ブログ
-