jqチートシート - JSONの抽出・絞り込み・変換

7分 で読める | 2026.04.10

公式ドキュメント

最頻出10項目

やりたいことコマンド
JSONを整形jq '.' data.json
キーを取得jq '.name' data.json
配列の先頭jq '.[0]' data.json
配列を展開jq '.[]' data.json
条件で絞るjq '.[] | select(.active)' data.json
配列を変換jq 'map(.name)' data.json
キー一覧jq 'keys' data.json
文字列を生で出力jq -r '.name' data.json
1行JSONで出力jq -c '.[]' data.json
シェル変数を渡すjq --arg name "$name" '.name = $name' data.json

jq は入力JSONを読み、結果を標準出力へ書きます。通常は元ファイルを直接変更しません。

値を取り出す

次のJSONを例にします。

{
  "name": "Ada",
  "profile": { "age": 18 },
  "tags": ["web", "js"]
}
フィルタ結果
.入力全体
.name"Ada"
.profile.age18
.missing?キーがなくてもエラーを抑える
.tags[0]"web"
.tags[-1]"js"
.tags[]配列要素を1件ずつ出力
.name, .profile.age複数の結果を出力

パイプ | は左の出力を右の入力へ渡します。

jq '.users[] | .name' data.json

selectで絞り込む

jq '.users[] | select(.active == true)' data.json
jq '.users[] | select(.age >= 18 and .role == "student")' data.json
jq '.users[] | select(.name | startswith("A"))' data.json

配列としてまとめたい場合は全体を [...] で囲みます。

jq '[.users[] | select(.active)]' data.json

mapで変換する

jq '.users | map(.name)' data.json
jq '.users | map({id, name})' data.json
jq '.scores | map(. * 2)' data.json

map(filter) は配列の各要素へフィルタを適用し、新しい配列を返します。.users[] | ... は結果を1件ずつ出す点が異なります。

配列の確認と集計

フィルタ用途
length要素数を返す
first / last最初 / 最後の要素
sort値を並べ替える
sort_by(.age)指定キーで並べ替える
unique重複を除く
unique_by(.id)指定キーの重複を除く
min / max最小値 / 最大値
add数値の合計や配列の結合
any / all1件以上 / 全件が真か
jq '.users | sort_by(.age) | map({name, age})' data.json
jq '.scores | {count: length, total: add, max: max}' data.json

sortunique は結果の配列を返し、入力ファイルを並べ替えるものではありません。

オブジェクトとキー

フィルタ用途
keysキーをソートして配列で返す
keys_unsorted元に近い順序でキーを返す
has("name")キーの有無を確認
to_entriesオブジェクトを {key, value} の配列へ変換
from_entries{key, value} の配列をオブジェクトへ戻す
. + {active: true}オブジェクトを浅く結合
.name // "unknown"false または null の場合に既定値
jq 'to_entries | map({key, value: (.value | tostring)}) | from_entries' data.json

//false も既定値へ置き換えます。false を有効値として残す必要がある場合は条件を明示してください。

パスを扱う

jq 'path(.profile.age)' data.json
jq 'getpath(["profile", "age"])' data.json
jq 'setpath(["profile", "age"]; 19)' data.json
jq 'delpaths([["secret"], ["profile", "token"]])' data.json

path はパスを配列で返し、getpathsetpath は動的なパスを読み書きします。これらも結果を標準出力へ返すだけで、入力ファイル自体は変更しません。

値の作成と更新

jq '{id: .user.id, displayName: .user.name}' data.json
jq '. + {checked: true}' data.json
jq '.count += 1' data.json
jq '.tags += ["json"]' data.json
jq 'del(.password, .token)' data.json
フィルタ用途
{name, age}同名キーで新しいオブジェクトを作る
{userName: .name}キー名を変えて作る
[.users[].name]複数出力を配列へまとめる
.field = value値を置き換えた結果を返す
.field |= filter現在値へフィルタを適用する
del(.field)キーを除いた結果を返す

jqの「代入」は、変更後のJSONを出力するフィルタです。入力ファイルへの保存は別途必要です。

型と変換

jq '.items[] | type' data.json
jq '.count | tonumber' data.json
jq '.id | tostring' data.json
jq '.name | ascii_downcase' data.json
フィルタ用途
typeobjectarraystring などを返す
tonumber数値形式の文字列を数値へ変換
tostring値を文字列表現へ変換
length配列・オブジェクト・文字列の長さ
empty結果を出力しない

型が一定でない外部データでは、変換前に typeselect(type == "number") で確認します。

よく使うオプション

オプション用途
-r文字列の引用符を外して出力
-cJSONを1行で出力
-e最後の出力が falsenull なら失敗終了
-n入力なしでJSONを生成
-s複数のJSON入力を1つの配列として読む
-Sオブジェクトのキーを並べ替える
--arg name value外部値を文字列として渡す
--argjson name json外部値をJSONとして渡す

シェルスクリプトで判定したい場合は -e が便利です。

if jq -e '.enabled == true' config.json > /dev/null; then
  echo "enabled"
fi

外部値を安全に渡す

name="Ada"
jq --arg name "$name" '.users[] | select(.name == $name)' data.json

limit=10
jq --argjson limit "$limit" '.users[:$limit]' data.json

変数を jq の式へ直接文字列連結すると、引用符の崩れや意図しない式の実行につながります。文字列は --arg、数値・配列・オブジェクトは妥当なJSONであることを確認して --argjson を使います。

JSON Linesと出力形式

1行に1つのJSONが並ぶJSON Linesは、そのまま1件ずつ処理できます。

jq -c 'select(.level == "error")' app.jsonl

複数のJSONをまとめたい場合は -s を使います。

jq -s 'map(.duration) | add' app.jsonl

JSON文字列だけを別コマンドへ渡す場合は -r、JSONの形を保って1行ずつ渡す場合は -c を選びます。

終了コードを利用する

CIやシェルスクリプトでは、表示内容ではなく終了コードで成否を判定できます。

jq -e '.version != null' package.json > /dev/null
status=$?
echo "$status"

-e は最後の出力が false または null なら非ゼロで終了します。ただし、ファイルが読めない、JSON構文が壊れている、フィルタが失敗した場合も非ゼロになります。必要なら標準エラーを記録して原因を分けてください。

APIレスポンスを確認する

curl --fail-with-body --silent --show-error \
  "https://api.example.com/users" |
  jq -c '.users[] | {id, name}'

APIトークンはコマンドへ直接書くと履歴へ残ることがあります。環境変数や利用中の秘密情報管理手段を使い、デバッグ出力にも含めないでください。信頼できないURLや値は、文字列連結ではなくコマンドの引数として安全に渡します。

APIがJSON以外のエラーページを返す可能性もあります。curl --fail-with-body などでHTTPエラーを検出し、jqの失敗と区別します。

ファイル更新時の注意

次の書き方は避けてください。シェルが先に出力先を空にするため、入力データを失います。

# 実行しない
jq '.enabled = true' config.json > config.json

別ファイルへ出力し、jqが成功した場合だけ置き換えます。

tmp_file="$(mktemp)"
if jq '.enabled = true' config.json > "$tmp_file"; then
  mv "$tmp_file" config.json
else
  rm -f "$tmp_file"
fi

重要な設定ファイルは、更新前にバックアップと差分確認も行ってください。

参考リソース

← 一覧に戻る
PR
PR
PR
PR