32blogby StudioMitsu

jqコマンド完全ガイド:JSONをターミナルで自在に操る

jqの基本フィルタからAPI応答加工・設定ファイル操作・スクリプト組み込みまで、実例付きで徹底解説。

13 min read
目次

「curl で取得した API レスポンスから特定のフィールドだけ抜き出したい」「package.json の依存関係を一覧にしたい」「JSON 形式のログからエラーだけ抽出したい」

こういう作業をターミナルで手軽にこなせるのが jq だ。JSON のスイスアーミーナイフとも呼ばれ、整形・フィルタ・変換・集計まで1つのコマンドでカバーする。

この記事では、基本的なフィルタから実践的なスクリプト活用まで、実際に動かせるコマンド例を交えて解説する。

jq とは

jq はコマンドラインで JSON を処理するための軽量ツールだ。C 言語で書かれていて、外部依存なしの単一バイナリで動作する。

主な特徴:

  • JSON 整形 — ミニファイされた JSON を見やすくフォーマット
  • フィールド抽出 — 必要な値だけピンポイントで取り出す
  • フィルタリング — 条件に合うデータだけ選別
  • 変換・集計 — データ形式の組み替えや計算
  • パイプライン — 複数の処理をつなげて複雑な加工も1行で

sedawk がテキスト処理の定番ツールであるように、jq は JSON 処理の定番だ。API を叩く機会が増えた今、curl と並んで必須のツールと言える。

インストール

powershell
# winget(推奨)
winget install jqlang.jq

# WSL を使っている場合は Linux と同じ
# sudo apt install jq

インストールできたらバージョンを確認しよう。

bash
jq --version
text
jq-1.8.1

基本的な使い方

JSON を整形する

最もシンプルな使い方は . フィルタだ。入力された JSON をそのまま整形して出力する。

bash
echo '{"name":"test","value":42,"active":true}' | jq '.'
json
{
  "name": "test",
  "value": 42,
  "active": true
}

ファイルから読み込む場合はファイル名を引数に渡す。

bash
jq '.' data.json

フィールドを取得する

ドット記法で特定のフィールドを取り出せる。

bash
echo '{"name":"jq","version":"1.8.1"}' | jq '.name'
text
"jq"

クォートなしの生の文字列が欲しい場合は -r(raw output)を使う。

bash
echo '{"name":"jq","version":"1.8.1"}' | jq -r '.name'
text
jq

ネストしたフィールド

ドットをつなげてネストの深い値にアクセスできる。

bash
echo '{"data":{"users":[{"name":"Alice","age":30}]}}' | jq '.data.users[0].name'
text
"Alice"

配列操作

bash
# 最初の要素
echo '[10,20,30]' | jq '.[0]'

# 最後の要素
echo '[10,20,30]' | jq '.[-1]'

# 配列の長さ
echo '[10,20,30]' | jq 'length'

# スライス(インデックス1から2まで)
echo '[10,20,30,40]' | jq '.[1:3]'

出力形式の制御

bash
# コンパクト出力(1行に圧縮)
echo '{"name":"test","value":42}' | jq -c '.'

# タブインデント
echo '{"name":"test","value":42}' | jq --tab '.'

# ソート済みキーで出力
echo '{"b":2,"a":1}' | jq -S '.'

フィルタとパイプ

jq の真価はフィルタの組み合わせにある。パイプ | でフィルタをつなげて、複雑な処理を組み立てられる。

配列イテレータ

[] で配列の各要素を展開する。

bash
echo '{"users":[{"name":"Alice"},{"name":"Bob"},{"name":"Charlie"}]}' \
  | jq '.users[].name'
text
"Alice"
"Bob"
"Charlie"

select — 条件フィルタ

select() で条件に合う要素だけ抽出する。

bash
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25},{"name":"Charlie","age":35}]}' \
  | jq '.users[] | select(.age > 28)'
json
{
  "name": "Alice",
  "age": 30
}
{
  "name": "Charlie",
  "age": 35
}

map — 配列の変換

map() は配列の各要素にフィルタを適用して、新しい配列を返す。

bash
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' \
  | jq '.users | map(.name)'
json
[
  "Alice",
  "Bob"
]

オブジェクトの構築

必要なフィールドだけ抜き出して新しいオブジェクトを作れる。

bash
echo '{"users":[{"name":"Alice","age":30,"email":"alice@example.com","role":"admin"}]}' \
  | jq '.users[] | {name: .name, email: .email}'
json
{
  "name": "Alice",
  "email": "alice@example.com"
}

文字列補間

\() で値を文字列に埋め込める。-r と組み合わせるのが定番だ。

bash
echo '{"users":[{"name":"Alice","email":"alice@example.com"},{"name":"Bob","email":"bob@example.com"}]}' \
  | jq -r '.users[] | "\(.name): \(.email)"'
text
Alice: alice@example.com
Bob: bob@example.com

条件分岐

bash
echo '{"status":"ok","data":"hello"}' \
  | jq 'if .status == "ok" then .data else "error: \(.status)" end'
text
"hello"

ソート・グループ化・集計

bash
# ソート
echo '[{"name":"Charlie","age":35},{"name":"Alice","age":30},{"name":"Bob","age":25}]' \
  | jq 'sort_by(.age)'

# ユニーク
echo '["apple","banana","apple","cherry","banana"]' | jq 'unique'

# 合計
echo '[10,20,30,40]' | jq 'add'

# 平均値
echo '[10,20,30,40]' | jq 'add / length'

keys と has

bash
# オブジェクトのキー一覧
echo '{"name":"test","version":"1.0","license":"MIT"}' | jq 'keys'

# キーの存在確認
echo '{"name":"test"}' | jq 'has("name")'

実践ユースケース

API レスポンスの加工

curl と組み合わせて API レスポンスから必要な情報を抽出するのは、jq の最も一般的な使い方だ。

bash
curl -s https://api.github.com/repos/jqlang/jq \
  | jq '{name: .name, stars: .stargazers_count, forks: .forks_count, license: .license.spdx_id}'
json
{
  "name": "jq",
  "stars": 31000,
  "forks": 1600,
  "license": "MIT"
}

ページネーション付きの API で複数ページの結果を結合する場合:

bash
for page in 1 2 3; do
  curl -s "https://api.github.com/users/octocat/repos?per_page=100&page=${page}"
done | jq -s 'flatten | map({name: .name, stars: .stargazers_count}) | sort_by(.stars) | reverse'

package.json の解析

プロジェクトの依存関係をざっと確認したいときに便利だ。

bash
# 依存パッケージの一覧
jq '.dependencies | keys' package.json
json
[
  "next",
  "react",
  "react-dom"
]
bash
# パッケージ名とバージョンを見やすく表示
jq -r '.dependencies | to_entries[] | "\(.key)@\(.value)"' package.json
text
next@^16.0.0
react@^19.0.0
react-dom@^19.0.0
bash
# dependencies と devDependencies の合計数
jq '{deps: (.dependencies | length), devDeps: (.devDependencies | length)}' package.json

ログファイルの JSON 解析

JSON Lines 形式(1行1JSON)のログファイルを解析する。

bash
# エラーログだけ抽出してタイムスタンプとメッセージを表示
cat app.log \
  | jq -r 'select(.level == "error") | "\(.timestamp) [\(.level)] \(.message)"'
text
2026-03-08T10:15:30Z [error] Database connection timeout
2026-03-08T10:18:45Z [error] Failed to process request
bash
# エラーレベルごとの件数を集計
cat app.log \
  | jq -s 'group_by(.level) | map({level: .[0].level, count: length})'
json
[
  { "level": "error", "count": 5 },
  { "level": "info", "count": 142 },
  { "level": "warn", "count": 23 }
]

設定ファイルの操作

JSON 形式の設定ファイルをコマンドラインから編集できる。

bash
# 値の更新
jq '.database.port = 5433' config.json > tmp.json && mv tmp.json config.json
bash
# フィールドの追加
jq '.database.ssl = true' config.json > tmp.json && mv tmp.json config.json
bash
# フィールドの削除
jq 'del(.debug)' config.json > tmp.json && mv tmp.json config.json
bash
# 2つの JSON ファイルをマージ(override が優先)
jq -s '.[0] * .[1]' base.json override.json > merged.json

スクリプト活用例

GitHub リポジトリ情報を CSV に変換

bash
#!/bin/bash
# github-repos-to-csv.sh
# 指定ユーザーの公開リポジトリ情報をCSVに変換する

USERNAME="${1:?Usage: $0 <github-username>}"
OUTPUT="repos.csv"

echo "name,stars,forks,language,updated" > "${OUTPUT}"

page=1
while true; do
  response=$(curl -s "https://api.github.com/users/${USERNAME}/repos?per_page=100&page=${page}")

  count=$(echo "${response}" | jq 'length')
  if [ "${count}" -eq 0 ]; then
    break
  fi

  echo "${response}" \
    | jq -r '.[] | [.name, .stargazers_count, .forks_count, (.language // "N/A"), .updated_at[:10]] | @csv' \
    >> "${OUTPUT}"

  page=$((page + 1))
done

total=$(tail -n +2 "${OUTPUT}" | wc -l)
echo "Exported ${total} repositories to ${OUTPUT}"

ポイント:

  • @csv フィルタが CSV フォーマットへの変換を自動処理する(クォートやエスケープ含む)
  • // "N/A" は alternative operator で、null の場合にデフォルト値を返す
  • ページネーションをループで処理して全リポジトリを取得する

複数 JSON ファイルの結合と集計レポート

bash
#!/bin/bash
# merge-json-reports.sh
# reports/ ディレクトリ内のJSONレポートを結合して集計する

REPORT_DIR="${1:?Usage: $0 <report-directory>}"

if [ ! -d "${REPORT_DIR}" ]; then
  echo "Error: Directory '${REPORT_DIR}' not found" >&2
  exit 1
fi

file_count=$(find "${REPORT_DIR}" -name "*.json" -type f | wc -l)
if [ "${file_count}" -eq 0 ]; then
  echo "Error: No JSON files found in '${REPORT_DIR}'" >&2
  exit 1
fi

# 全JSONファイルを結合して集計
find "${REPORT_DIR}" -name "*.json" -type f -exec cat {} + \
  | jq -s '{
    total_files: length,
    total_records: (map(.records // 0) | add),
    total_errors: (map(.errors // 0) | add),
    avg_duration_ms: (map(.duration_ms // 0) | add / length | floor),
    statuses: (group_by(.status) | map({status: .[0].status, count: length})),
    date_range: {
      earliest: (map(.timestamp) | sort | first),
      latest: (map(.timestamp) | sort | last)
    }
  }'

echo ""
echo "Processed ${file_count} files from ${REPORT_DIR}"

ポイント:

  • -s(slurp)で複数の JSON を1つの配列にまとめる
  • group_bymap の組み合わせでステータス別集計
  • // 0 でフィールドが存在しない場合のエラーを防ぐ
  • floor で小数点以下を切り捨て

セキュリティの注意点

信頼できない JSON を処理する場合は、以下の点に注意してほしい。

  • バージョンを最新に保つ — パーサーの脆弱性は定期的に発見される。jq --version で現在のバージョンを確認し、1.8.1 未満なら即アップデート
  • 入力サイズを制限する — 巨大な JSON を処理するとメモリを大量消費する。パイプラインの前段で head -c などでサイズを制限するか、ストリーミングパーサー(--stream)を検討する
  • シェルインジェクションに注意 — jq の出力をそのまま evalbash -c に渡すのは危険だ。必ず jq -r で取り出した値をクォートして使う
bash
# 危険な例(絶対にやらないこと)
eval $(curl -s https://example.com/config.json | jq -r '.command')

# 安全な例(変数に代入してクォート)
value=$(curl -s https://example.com/config.json | jq -r '.setting')
echo "Setting: ${value}"

まとめ

jq は JSON をターミナルで自在に操るための必須ツールだ。

  • 基本. で整形、.field で抽出、-r で生文字列出力
  • フィルタselect で条件抽出、map で変換、パイプで組み合わせ
  • 実践 — API レスポンス加工、設定ファイル編集、ログ解析
  • スクリプト@csv 変換、-s で結合、シェルスクリプトへの組み込み

curl でデータを取得し、jq で加工し、sed・awk でテキスト整形するという流れを身につければ、ターミナルでのデータ処理が格段に効率化する。まずは curl ... | jq '.' から始めてみてほしい。

CLI ツールの全体像は CLIツール完全マップ も参考にしてほしい。