すぐ使える!「jqplay」か「jq」でJSONから欲しい情報をリスト化して抽出する方法

長いJSONデータ

WebAPIサーバーにリクエストを投げて、返ってきたレスポンスが長いJSONデータでした。目視で欲しい情報を全て追うのは難しかったため、パース(parse = 構文解析)してその中から欲しいデータをリスト化して抽出する必要がありました。

jq」という短い名前のプログラムを使うと、簡単にパースすることができました。

「jqplay」で簡単に済ませる

後述するjqの使い方を知っている人は、以下のサイトでjqのFilter(フィルター)JSONを入力するだけで、すぐに自動でjqのパースされた出力を得ることができます。

これならブラウザ上だけで完結します。JSONから整形した情報が欲しいだけの場合、jqをインストールしないで、このサイトをいじるだけで済むかもしれません。

「jqplay」の実行画面

「jq」をインストールする

jq」を使ってJSONをパースするプログラムを実装する場合、jqのインストールが必要です。

Macの場合、以下のコマンドを打つとgithubから実行ファイルをダウンロードできます。jqと打つだけで使えるようにしたいので、今回はPATHが通ったディレクトリ/usr/local/binにダウンロードしたファイルを配置しました。

# PATHが通ったディレクトリの確認
$ echo ${PATH}
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
$ 

# jqの実行ファイルをダウンロードする
$ curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-osx-amd64 -o /usr/local/bin/jq
$ ls -l /usr/local/bin/jq 
-rw-r--r--  1 stedplay  admin  649996 12 21 02:14 /usr/local/bin/jq
$ 

# 実行権限を付与する
$ chmod +x /usr/local/bin/jq
$ ls -l /usr/local/bin/jq 
-rwxr-xr-x  1 stedplay  admin  649996 12 21 02:14 /usr/local/bin/jq
$ jq --version
jq-1.5
$

以下のページでも実行ファイルを環境別にダウンロードできるので、パスが通ったディレクトリに配置すればWindowsやLinuxでも同様に使用できます。

Command-line JSON processor. Contribute to jqlang/jq development by creating an account on GitHub.

jqの実行ファイルのダウンロードページ

「jq」を使ってみる

基本的な使い方

以下のように、JSONの文字列をあるコマンドからjqへ|(パイプ)で渡すと、設定したfilterに応じた整形をして出力してくれます。

echo ‘json_string’ | jq ‘filter

下記は取得したJSONに対して、キー(ここでは“key”という要素)に対応する値リストとして抽出するまでの考え方の流れです。

# 取得したJSONのサンプル
$ JSON='{"results": [{"key": "value1"}, {"key": "value2"}]}'

# 1行に記載されたjsonを見やすく整形して表示するだけ
$ echo ${JSON} | jq '.'
{
  "results": [
    {
      "key": "value1"
    },
    {
      "key": "value2"
    }
  ]
}
$ 

# results要素(配列)を取得
$ echo ${JSON} | jq '.["results"]'
[
  {
    "key": "value1"
  },
  {
    "key": "value2"
  }
]
$

# results配列の1番目(添字0)の要素を取得
$ echo ${JSON} | jq '.["results"][0]'
{
  "key": "value1"
}
$ 

# results配列の2番目(添字1)の要素を取得
$ echo ${JSON} | jq '.["results"][1]'
{
  "key": "value2"
}
$ 

# results配列の全ての要素を取得
$ echo ${JSON} | jq '.["results"][]'
{
  "key": "value1"
}
{
  "key": "value2"
}
$ 

# results配列の全ての要素に含まれるkey要素を取得
$ echo ${JSON} | jq '.["results"][]["key"]'
"value1"
"value2"
$ 

# rオプションでダブルクォーテーションを除去する
$ echo ${JSON} | jq -r '.["results"][]["key"]'
value1
value2
$ 

filterに変数を含める使い方

後述する説明を簡単にするため、ここでは以下の単語を定義します。

単語 意味
VAR_SHELL shell内で定義した変数名
VAR_FILTER jqのfilterで使用する変数名

filterの変数を「数値」として扱いたい場合

--argjsonオプションを用いて、jqで使用する変数を定義します。

jq --argjson VAR_FILTER ${VAR_SHELL} ‘.[$VAR_FILTER]’

主に、JSON内の配列の添字を指定するための変数に使用します。

# 取得したJSONのサンプル(上記と同一)
$ JSON='{"results": [{"key": "value1"}, {"key": "value2"}]}'

# results配列の1番目(添字0)の要素を取得
$ INDEX=0
$ echo ${JSON} | jq --argjson index ${INDEX} '.["results"][$index]'
{
  "key": "value1"
}
$ 

# results配列の2番目(添字1)の要素を取得
$ INDEX=1
$ echo ${JSON} | jq --argjson index ${INDEX} '.["results"][$index]'
{
  "key": "value2"
}
$

filterの変数を「文字列」として扱いたい場合

--argオプションを用いて、jqで使用する変数を定義します。

jq --arg VAR_FILTER ${VAR_SHELL} ‘.[$VAR_FILTER]’

主に、JSON内のキーとして扱うための変数に使用します。

# ヒアドキュメントでjsonファイルのサンプルを作る
$ cat << EOD > urls.json
{
  "local": {
    "url": "http://localhost"
  },
  "production": {
    "url": "http://example.com"
  }
}
EOD
$

# 変数をローカル環境に設定
$ SERVER_ENV=local
$ cat urls.json | jq -r --arg env ${SERVER_ENV} '.[$env]["url"]'
http://localhost
$ 

# 変数を本番環境に設定
$ SERVER_ENV=production
$ cat urls.json | jq -r --arg env ${SERVER_ENV} '.[$env]["url"]'
http://example.com
$
より詳しい使い方は、公式マニュアルマニュアルの日本語訳を参照ください。

まとめ

「jqplay」の紹介と、「jq」のインストール方法と基本的な使い方をまとめました。jqを使うと簡単にJSONデータをパースして欲しい情報を抽出することができます。

APIコールすると結果がJSONで返ってくるサーバーを扱うことが多いので、すぐに欲しい情報を整形して取得できるように、予めjqをちゃんと使いこなせるようにしておいた方が良さそう。