
はじめに:なぜjqを学ぶのか
私は日頃からさまざまなワークフローの自動化を試みています。その中で繰り返し登場するのが、JSONデータの処理という課題です。
たとえば、YouTube動画のメタデータを取得して整形したり、APIのレスポンスから必要な情報だけを抜き出したり。こうした作業を手作業で行うのは現実的ではありません。かといって、毎回Pythonスクリプトを書くのも少々重たい。
そこで活躍するのが jq です。
jqは「コマンドラインのJSON処理ツール」と表現されることが多いのですが、私はむしろ「JSONに対するSQL」のようなものだと捉えています。データベースからSQLでデータを抽出するように、jqはJSONから必要な情報を抽出・変換・整形できます。
この記事では、jqの基本概念から実践的な使い方までを解説します。これを読むと、シェルスクリプトとjqを組み合わせた効率的なワークフローを構築できるようになるはずです。
jqとは何か
jq は、軽量かつ柔軟なコマンドライン用JSON処理ツールです。JSONデータを標準入力またはファイルから受け取り、指定した「フィルター」に基づいて加工・出力します。
なぜjqが必要なのか
シェル環境では、テキスト処理に grep、awk、sed といったツールが使われます。しかし、これらは「行指向」のツールです。JSONのような階層構造を持つデータには適していません。
JSONは本来、以下のような構造を持っています:
{ "user": { "name": "tanaka", "email": "tanaka@example.com" }, "posts": [ {"title": "記事1", "views": 100}, {"title": "記事2", "views": 250} ] }
このようなネストした構造から user.name の値だけを取り出したり、posts 配列から views が200以上の記事だけを抽出するといった操作は、grep では困難です。
jqは、JSONの構造を理解した上で操作できるツールとして設計されており、こうした課題を解決します。
インストール方法
主要なプラットフォームではパッケージマネージャーからインストールできます:
# Ubuntu/Debian sudo apt-get install jq # macOS (Homebrew) brew install jq # Windows (Chocolatey) choco install jq
インストール後は jq --version で確認できます。
基本概念:フィルターを理解する
jqを使いこなす上で最も重要な概念が「フィルター」です。フィルターとは、入力されたJSONに対して何らかの処理を行い、結果を出力する式のことです。
アイデンティティフィルター .
最もシンプルなフィルターは .(ドット)です。これは「入力をそのまま出力する」という意味を持ちます。
echo '{"name": "tanaka", "age": 30}' | jq '.'
出力:
{ "name": "tanaka", "age": 30 }
一見無意味に思えますが、jqはJSONを自動的に整形(pretty-print)するため、圧縮されたJSONを読みやすくする用途でよく使われます。
オブジェクトのプロパティアクセス .key
オブジェクトから特定のキーの値を取り出すには、.key の形式を使います:
echo '{"name": "tanaka", "age": 30}' | jq '.name'
出力:
"tanaka"
ネストしたオブジェクトにも .parent.child のようにアクセスできます:
echo '{"user": {"name": "tanaka"}}' | jq '.user.name'
配列のアクセス .[index] と .[]
配列の特定のインデックスにアクセスするには .[index] を使います(0始まり):
echo '["apple", "banana", "cherry"]' | jq '.[1]'
出力:
"banana"
配列のすべての要素を順番に処理するには .[] を使います:
echo '["apple", "banana", "cherry"]' | jq '.[]'
出力:
"apple" "banana" "cherry"
パイプとフィルターの組み合わせ
jqの真価は、複数のフィルターを パイプ | で連結できることにあります。これは、UNIXシェルのパイプと同じ発想です。
例:オブジェクト配列から特定のフィールドを抽出
以下のようなJSONデータがあるとします:
[ {"title": "記事1", "views": 100}, {"title": "記事2", "views": 250}, {"title": "記事3", "views": 50} ]
各オブジェクトの title だけを抽出するには:
echo '[{"title": "記事1", "views": 100}, {"title": "記事2", "views": 250}]' | jq '.[] | .title'
出力:
"記事1" "記事2"
処理の流れを分解すると:
.[]で配列の各要素を順番に出力|で次のフィルターに渡す.titleで各要素からtitleプロパティを抽出
実践編:よく使うパターン
ここからは、実際の作業でよく使うjqのパターンを紹介します。
条件でフィルタリング:select()
特定の条件を満たす要素だけを抽出するには select() を使います:
echo '[{"name": "apple", "price": 100}, {"name": "banana", "price": 80}]' | jq '.[] | select(.price > 90)'
出力:
{ "name": "apple", "price": 100 }
配列のスライス .[start:end]
配列の一部を切り出すにはスライス記法を使います:
echo '["a", "b", "c", "d", "e"]' | jq '.[1:3]'
出力:
["b", "c"]
負のインデックスも使えます。[-2:] で末尾2要素を取得できます。
新しいオブジェクトの構築
入力データから新しい形のオブジェクトを作成できます:
echo '{"first": "Taro", "last": "Yamada", "age": 30}' | jq '{fullName: (.first + " " + .last), age}'
出力:
{ "fullName": "Taro Yamada", "age": 30 }
文字列補間 \()
文字列内に式の結果を埋め込むには \() を使います:
echo '{"title": "記事タイトル", "author": "tanaka"}' | jq '"TITLE: \(.title)\nAUTHOR: \(.author)"'
出力:
"TITLE: 記事タイトル\nAUTHOR: tanaka"
-r オプション(raw output)を付けると、クォートなしで出力されます:
echo '{"title": "記事タイトル", "author": "tanaka"}' | jq -r '"TITLE: \(.title)\nAUTHOR: \(.author)"'
出力:
TITLE: 記事タイトル AUTHOR: tanaka
実践例:YouTubeメタデータの抽出
私のワークフローでは、YouTube動画のメタデータをjqで処理しています。実際の例を見てみましょう。
yt-dlp コマンドでダウンロードしたメタデータJSONから必要な情報を抽出します:
jq -r '"TITLE: \(.title)\nCHANNEL: \(.uploader)\nDATE: \(.upload_date)\nDESCRIPTION: \(.description)"' video_metadata.json
また、コメントの上位10件を抽出・整形するには:
jq -r '.comments[:10] | .[] | "- **\(.author)** (\(.like_count // 0) likes): \(.text | gsub("\n"; " ") | .[0:200])"' video_metadata.json
このコマンドのポイント:
.comments[:10]— コメント配列の先頭10件を取得.like_count // 0—like_countが null の場合は 0 を代用(Alternative operator)gsub("\n"; " ")— 改行をスペースに置換.[0:200]— 文字列を200文字に制限
jqを学ぶためのリソース
jqは非常に多機能なツールです。この記事で紹介したのは基礎的な部分に過ぎません。
さらに深く学ぶには、以下のリソースが役立ちます:
まとめ
jqは、コマンドラインでJSONデータを処理するための強力なツールです。
- フィルター構文
.key、.[]、.[index]でデータにアクセス - パイプ
|で処理を連結し、複雑な変換を実現 select()で条件フィルタリング- 文字列補間
\()と-rオプションで整形済みテキストを出力
一度覚えてしまえば、APIレスポンスの処理、ログ解析、設定ファイルの変換など、さまざまな場面で活用できます。ぜひ手を動かして試してみてください。