広告が嫌いですか? 行く 広告なし 今日

jq 1行文 CLIでスクリプトを書かずにJSONをフィルタおよび変換

更新日

バックエンド開発者およびDevOps向けの7つの実用的なjqレシピ — select、map、to_entries、del、group_by、実際のAPIリシェイプをカバー。すべてのパターンに対して入力と出力が示されています。

jq 1行文:CLIでスクリプトを書かずにJSONをフィルタおよび変換 1

あなたはターミナルで最小化されたAPIレスポンスを見ています。3つのフィールドを抽出し、nullをフィルタリングし、結果を他のコマンドにパイプする必要があります。これにPythonスクリプトを書くのは20行で、2分も時間がないのです。 jq パターンを知っているなら、1つのコマンドで処理できます。

以下の7つのレシピ。それぞれがAPIレスポンスやログファイルを扱う際に繰り返し使うパターンをカバーしています。すべてのレシピには入力、コマンド、出力が示されています。

インストール

brew install jq        # macOS
apt-get install jq     # Ubuntu/Debian
apk add jq             # Alpine (Docker images)

レシピ1: 配列内のすべてのオブジェクトからフィールドを抽出

最もよく行われることです。 jq: JSON配列内のすべてのアイテムから1つのフィールドを取得します。

入力 (users.json)

[
  {"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"},
  {"id": 2, "name": "Bob",   "email": "bob@example.com",   "role": "user"},
  {"id": 3, "name": "Carol", "email": "carol@example.com", "role": "user"}
]
jq '.[].name' users.json
# → "Alice"
#   "Bob"
#   "Carol"  (newline-separated stream)

.[] 配列内のすべての要素を繰り返します; .name フィールドを取得します。出力はストリームです — 他のコマンドにパイプするのに便利です。適切なJSON配列を必要とする場合:

jq 'map(.name)' users.json
# → ["Alice", "Bob", "Carol"]

map(.name) は、以下のプロパティのショートハンドです。 [.[] | .name] — 各アイテムに対して式を適用し、結果を配列に包みます。これはよく使われます。 map() よく使われます。

レシピ2: を使用してフィルタリング select

条件に一致するオブジェクトだけを残し、残りを削除します。

jq 'map(select(.role == "admin"))' users.json
[
  {"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"}
]

select(expr) 式が真の場合にアイテムを通過させます — それ以外は消えます。 を包むことで出力が配列として保持されます。さらに例: map() keeps the output as an array. More examples:

# Numeric comparison
jq 'map(select(.score > 80))' results.json

# Not-null check
jq 'map(select(.error != null))' events.json

# String contains (requires test)
jq 'map(select(.message | test("timeout")))' logs.json

レシピ3: を使用してオブジェクトを再構成 map

必要なフィールドだけを選び、必要に応じて同じ処理で名前を変更します。

jq 'map({name: .name, role: .role})' users.json
[
  {"name": "Alice", "role": "admin"},
  {"name": "Bob",   "role": "user"},
  {"name": "Carol", "role": "user"}
]

各アイテムに対して新しいオブジェクトリテラルを作成します。キーをリネームしたい場合は、コロンの左側を変更します:

jq 'map({username: .name, access_level: .role})' users.json

1つのショートカットでキー入力を節約できます: {name} は、名前 {name: .name}。フィールドをそのまま使う場合は、キーを2回書く必要はありません:

jq 'map({id, name, role})' users.json

レシピ4: を使用してキーをリネーム to_entriesfrom_entries

map キーが存在することを知っている場合に有効です。キー自体を変換する必要がある場合 — プレフィックスを追加、名前規則を変換、またはマップに基づいてリネームする場合 — to_entries が適切なパターンです。

入力 (config.json)

{"api_url": "https://api.example.com", "timeout": 30, "retry_count": 3}
# Add cfg_ prefix to every key
jq 'to_entries | map(.key = "cfg_" + .key) | from_entries' config.json
{"cfg_api_url": "https://api.example.com", "cfg_timeout": 30, "cfg_retry_count": 3}

to_entries{"k": "v"} の中へ [{"key": "k", "value": "v"}]変換します。配列内の項目を変更した後、 from_entries オブジェクトを再構成します。特定のキーだけをリネームしたい場合、他のキーには影響を与えません:

jq 'to_entries | map(if .key == "api_url" then .key = "endpoint" else . end) | from_entries' config.json

レシピ5: を使用してフィールドを削除 del

リシェイプの逆:すべてを保持し、いくつかの特定のフィールドを削除します。主な用途は、ログに記録する前または第三者サービスにパラメータを渡す前に、センシティブデータを削除することです。

jq 'map(del(.email))' users.json
[
  {"id": 1, "name": "Alice", "role": "admin"},
  {"id": 2, "name": "Bob",   "role": "user"},
  {"id": 3, "name": "Carol", "role": "user"}
]

複数のフィールドを一度に削除、またはネストされたパスを削除:

# Multiple top-level fields at once
jq 'del(.password, .token, .refresh_token)' user.json

# Nested path
jq 'del(.user.internal_id)' response.json

# All fields named "debug" at any depth (recursive descent)
jq 'del(.. | .debug? // empty)' response.json

レシピ6: フィルタ、リシェイプ、並べ替えを1回で実行

これらの基本操作を連結する実際の報酬です。ページネートされたAPIレスポンスを扱う際に頻繁に現れるパターンは、ネストされた配列に降り込み、フィルタリングし、オブジェクトをリシェイプし、結果を並べ替えることです。

入力 (repos.json)

{
  "total_count": 3,
  "items": [
    {"id": 1, "name": "repo-alpha", "stargazers_count": 142, "language": "Go",     "private": false},
    {"id": 2, "name": "repo-beta",  "stargazers_count": 89,  "language": "Python", "private": true},
    {"id": 3, "name": "repo-gamma", "stargazers_count": 310, "language": "Go",     "private": false}
  ]
}
jq '.items
  | map(select(.private == false and .language == "Go"))
  | sort_by(-.stargazers_count)
  | map({name, stars: .stargazers_count})' repos.json
[
  {"name": "repo-gamma", "stars": 310},
  {"name": "repo-alpha", "stars": 142}
]

パイプライン:

  • .items — ネストされた配列に降り込む
  • map(select(...)) — 1回のパスでフィルタリング; and 条件を連結
  • sort_by(-.stargazers_count) — 降順ソートのため値を否定; sort_by(.field) だけが昇順を提供
  • map({name, stars: .stargazers_count}) — 最終的なリシェイプ; {name} は、以下のプロパティのショートハンドです。 {name: .name}

レシピ7: ログレベルをカウント group_by

構造化されたログ出力の頻度分析 — データベースは不要、awkの技巧は不要。

入力 (logs.json)

[
  {"level": "error", "msg": "connection timeout",     "service": "auth"},
  {"level": "info",  "msg": "request received",       "service": "api"},
  {"level": "error", "msg": "null pointer exception", "service": "worker"},
  {"level": "warn",  "msg": "slow query detected",    "service": "db"},
  {"level": "error", "msg": "rate limit exceeded",    "service": "api"}
]
jq 'group_by(.level) | map({level: .[0].level, count: length}) | sort_by(-.count)' logs.json
[
  {"level": "error", "count": 3},
  {"level": "info",  "count": 1},
  {"level": "warn",  "count": 1}
]

group_by(.level) 配列の配列を返します — 各サブ配列は同じレベル値を持つすべてのエントリを保持します。 .[0].level グループ内の最初のアイテムからレベル名を取得します; length グループ内のエントリの数をカウントします。

同じクエリでサービスごとの分解を追加:

jq 'group_by(.level) | map({
  level:    .[0].level,
  count:    length,
  services: map(.service) | unique
})' logs.json

速携帯用参考

上記のパターンを表形式にまとめたもの。必要に応じてすぐに確認できるようにします:

何をしたいかjq表現
フィールドのすべての値map(.field)
一致するアイテムをフィルタリングmap(select(.field == "val"))
各オブジェクトをリシェイプmap({newKey: .oldKey})
すべてのキーをリネームto_entries | map(.key = ...) | from_entries
フィールドを削除map(del(.field1, .field2))
昇順ソートsort_by(.field)
降順ソートsort_by(-.field)
グループでカウントgroup_by(.field) | map({key: .[0].field, count: length})
オブジェクトのすべてのキーを取得keys
配列内のアイテム数をカウントlength
フィールドのユニークな値map(.field) | unique

開始前に:ブロブをコントロール

APIレスポンスはしばしば最小化または深くネストされています。必要なパスがわからない場合は、JSONを JSONフォーマッタ — カッコブレインで表示され、折りたたみ可能なノードを持つため、必要なパスを確認できます。 jq — 表現を書く前に、変換を実行します。変換後、 JSON比較 ツールは、リシェイプまたはフィールドを削除する際に、意図しない変更がないか確認するために、前後差分を確認するのに役立ちます。

これらの7つのパターンは、コマンドラインで行うJSON処理の大部分をカバーしています。実際の力は、それらを連結することです — フィルタ、リシェイプ、ソートができれば、ほとんどのAPIレスポンスをスクリプトファイルに触らずに処理できます。

広告なしで楽しみたいですか? 今すぐ広告なしで

拡張機能をインストールする

お気に入りのブラウザにIOツールを追加して、すぐにアクセスし、検索を高速化します。

に追加 Chrome拡張機能 に追加 エッジ拡張 に追加 Firefox 拡張機能 に追加 Opera 拡張機能

スコアボードが到着しました!

スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!

ニュースコーナー 技術ハイライト付き

参加する

価値ある無料ツールの提供を継続するためにご協力ください

コーヒーを買って