この記事について
CLIでAPIレスポンスや設定ファイルのJSONを確認・加工する場面で、jq のフィルタ構文を毎回調べ直すのは時間の無駄だ。この記事では、実務で繰り返し使うパターンをリファレンスとしてまとめる。
- 対象環境: Linux / macOS
- 確認バージョン: jq 1.6 / jq 1.7
- 確認時点: 2026年6月
ここがポイント:
-rオプションとselect()・map()の組み合わせを押さえると、日常のJSON操作はほぼカバーできる。
インストール確認
# Ubuntu / Debian
sudo apt install jq
# macOS (Homebrew)
brew install jq
# バージョン確認
jq --version
# jq-1.7.1
基本フィルタ
ドット(.)とフィールドアクセス
# 整形して出力(最もよく使う)
cat response.json | jq '.'
# フィールド取得
echo '{"name":"Alice","age":30}' | jq '.name'
# "Alice"
# ネストしたフィールド
echo '{"user":{"id":1,"name":"Alice"}}' | jq '.user.name'
# "Alice"
# 存在しないキーは null(エラーにはならない)
echo '{"name":"Alice"}' | jq '.age'
# null
配列操作
# 配列を展開(各要素を個別に出力)
echo '[1,2,3]' | jq '.[]'
# インデックスアクセス
echo '[10,20,30]' | jq '.[1]'
# 20
# スライス
echo '[10,20,30,40]' | jq '.[1:3]'
# [20,30]
# 最後の要素
echo '[10,20,30]' | jq '.[-1]'
# 30
よく使う組み込み関数
length / keys / has
# 配列の長さ
echo '[1,2,3]' | jq 'length'
# 3
# オブジェクトのキー一覧
echo '{"a":1,"b":2}' | jq 'keys'
# ["a","b"]
# キーの存在確認
echo '{"name":"Alice"}' | jq 'has("name")'
# true
map / select
実務で最も使う組み合わせ。配列のフィルタリングや変換に使う。
# 全要素に処理を適用
echo '[1,2,3,4]' | jq 'map(. * 2)'
# [2,4,6,8]
# 条件に合う要素だけ取り出す
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' \
| jq '[.[] | select(.age >= 30)]'
# [{"name":"Alice","age":30}]
# map + select の組み合わせ
echo '[1,2,3,4,5]' | jq '[.[] | select(. > 3)]'
# [4,5]
to_entries / from_entries
オブジェクトを {key, value} の配列に変換して操作したいときに使う。値の一括変換などで便利。
echo '{"a":1,"b":2,"c":3}' | jq 'to_entries'
# [{"key":"a","value":1},{"key":"b","value":2},{"key":"c","value":3}]
# 値を変換してオブジェクトに戻す
echo '{"a":1,"b":2}' | jq 'to_entries | map(.value *= 10) | from_entries'
# {"a":10,"b":20}
複数フィールドの抽出・整形
# フィールドを絞ったオブジェクトに再構成
echo '{"id":1,"name":"Alice","role":"admin","score":95}' \
| jq '{name, role}'
# {"name":"Alice","role":"admin"}
# 文字列補間で結合
echo '{"first":"Alice","last":"Smith"}' \
| jq '"\(.first) \(.last)"'
# "Alice Smith"
# 配列から特定フィールドだけ抜き出す
echo '[{"id":1,"name":"A"},{"id":2,"name":"B"}]' \
| jq '[.[].name]'
# ["A","B"]
オプション整理
よく使うオプションをまとめる。
| オプション | 意味 | 使いどころ |
|---|---|---|
-r | 文字列のクォートを外す(raw output) | シェル変数に代入するとき |
-e | null/false のとき終了コード1を返す | スクリプトの条件分岐 |
-n | 標準入力をJSONとして読まない(null入力) | -n '1,2,3' などで入力を生成する |
-s | 複数のJSONを1つの配列にまとめる(slurp) | 複数行JSONの一括処理 |
-c | 1行に圧縮出力(compact) | ログ出力・ファイル書き込み |
-f filter.jq | フィルタをファイルから読む | フィルタが長くなったとき |
--arg key val | シェル変数を文字列としてjqに渡す | 動的なフィルタ条件 |
--argjson key val | JSON値としてシェル変数を渡す | 数値・配列との比較 |
-r は実務でほぼ必須。 jq '.name' は "Alice" とクォート付きで返すが、jq -r '.name' なら Alice になる。シェル変数に代入するときに -r を忘れると、クォートが変数に含まれて意図しない挙動につながる。
実務でよく使うパターン
シェル変数をフィルタに渡す
TARGET_USER="Alice"
echo '[{"name":"Alice"},{"name":"Bob"}]' \
| jq --arg user "$TARGET_USER" '[.[] | select(.name == $user)]'
--arg で渡した値は $user として参照できる。フィルタ中に直接シェル変数展開("$TARGET_USER")を使うと、クォートやエスケープが絡んで壊れやすいので --arg を使う。
null のデフォルト値(// 演算子)
//(alternative operator)は、左辺が null または false のときに右辺を返す。
echo '{"name":"Alice"}' | jq '.age // 0'
# 0
echo '{"name":"Alice","age":null}' | jq '.age // "不明"'
# "不明"
配列を TSV / CSV に変換
echo '[{"name":"Alice","score":95},{"name":"Bob","score":80}]' \
| jq -r '.[] | [.name, .score] | @tsv'
# Alice 95
# Bob 80
@csv に変えれば CSV 形式になる。スプレッドシートに貼り付けるときに使える。
オプションフィールドを安全に取得(? 演算子)
存在しないキーや null フィールドへのアクセスをエラーにしたくないときに使う。
echo '{"data":null}' | jq '.data.items?'
# null(エラーにならない)
注意点と落とし穴
null の伝播
jq では存在しないフィールドへのアクセスはエラーにならず null が伝播する。スクリプトで使う場合、予期しない null が出力に紛れ込む原因になる。-e オプションを組み合わせて存在チェックを入れると安全。
# -e: null/false のとき終了コード1を返す
value=$(echo '{"name":null}' | jq -re '.name') || echo "値が取得できませんでした"
大きな整数の精度落ち
jq は内部で IEEE 754 倍精度浮動小数点数を使うため、53ビット超の整数は精度が落ちる。SNSのID(64bit整数)などを扱う場合は文字列として保持する設計が必要。
echo '{"id": 1234567890123456789}' | jq '.id'
# 1234567890123456800 ← ずれる
複数行JSON(JSON Lines)の処理
APIが改行区切りで複数のJSONオブジェクトを返すNDJSON / JSON Lines形式の場合、-s で一括スラープするか各行を個別に処理する。
# JSON Lines を配列にまとめてフィルタ
cat events.jsonl | jq -s '[.[] | select(.type == "click")]'
まとめ
| 操作 | 使うフィルタ・オプション |
|---|---|
| フィールド取得 | .key, .[index] |
| 条件フィルタ | select() |
| 変換・マッピング | map() |
| オブジェクト分解・再構成 | to_entries / from_entries |
| null デフォルト値 | // 値 |
| シェル変数の注入 | --arg, --argjson |
| クォートなし文字列出力 | -r |
| TSV/CSV変換 | @tsv, @csv |
次に確認したい発展的な構文は次の通り。
reduce構文(累積・集計処理)envオブジェクト(環境変数の参照)@base64dでBase64デコードpath()式でフィールドのパスを取得debugでパイプ途中のデバッグ出力を挟む
コメント