AI

jqの使い方完全ガイド【インストールから応用まで】

jqの使い方完全ガイド【インストールから応用まで】

現代の開発において、JSONはデータ交換の標準形式です。Web APIのレスポンス、設定ファイル、ログデータなど、日々大量のJSONデータに触れる機会があります。

jqがない世界では、これらのJSONデータを扱う作業は骨の折れるものです。巨大なAPIレスポンスから必要な情報を見つけ出すには、手動でスクロールしたり、grepawkのような汎用ツールで無理やりパースしようとしたりするでしょう。しかし、JSONの複雑な構造を理解せずに行うこれらの操作は、時間と労力を消費し、時には誤った結果を招きます。

一方、jqがある世界では、JSONデータの操作が劇的に変わります。あなたは数行のシンプルなコマンドで、巨大なJSONから特定のフィールドを抽出し、データをフィルタリングし、望む形式に変換できます。デバッグ作業は迅速になり、スクリプトは簡潔になります。jqは、開発者の生産性を飛躍的に向上させる強力なツールです。

この記事では、jqのインストール方法から、基本的な使い方、さらに実践的な応用例までを詳しく解説します。

jqとは

jqは「JSONのsed」と表現される、軽量で柔軟なコマンドラインJSONプロセッサです。sedawkがテキストデータを扱うように、jqはJSONデータを扱います。

このツールはC言語で書かれており、実行時の依存関係がありません。そのため、様々な環境で手軽に利用できます。JSONデータをスライス(部分抽出)、フィルタリング(条件による絞り込み)、マップ(変換)、トランスフォーム(構造変更)といった操作を、パイプラインを介して効率的に実行可能です。

JSON形式が広く普及するにつれて、CLI環境でJSONを直感的に操作できるツールの需要が高まりました。そのニーズに応える形でjqは誕生し、今では多くの開発者にとって不可欠なツールとなっています。

インストール方法

jqのインストールは非常に簡単です。お使いのOSや環境に合わせて、以下のいずれかの方法を選んでください。

macOS

Homebrewを利用するのが最も一般的です。

brew install jq

Linux

多くのLinuxディストリビューションでは、パッケージマネージャーを使ってインストールできます。

Debian / Ubuntu

sudo apt-get update
sudo apt-get install jq

CentOS / RHEL / Fedora

sudo yum install jq
# または
sudo dnf install jq

Windows

Windowsでは、ChocolateyやScoopといったパッケージマネージャー、または直接バイナリをダウンロードする方法があります。

Chocolateyを使用する場合

choco install jq

Scoopを使用する場合

scoop install jq

バイナリを直接ダウンロードする場合

GitHubのリリースページから、お使いのシステムに合った実行ファイルをダウンロードし、PATHが通っているディレクトリに配置してください。 jq GitHub Releases

Docker

Docker環境があれば、イメージをプルしてすぐにjqを利用できます。インストール不要で手軽に試せる方法です。

Dockerでpackage.jsonのバージョンを抽出する例

カレントディレクトリのpackage.jsonファイルを標準入力からjqに渡します。

docker run --rm -i ghcr.io/jqlang/jq:latest < package.json '.version'

Dockerでボリュームをマウントしてファイルパスを指定する例

ファイルを直接指定したい場合は、ボリュームマウントを利用します。

docker run --rm -i -v "$PWD:$PWD" -w "$PWD" ghcr.io/jqlang/jq:latest '.version' package.json

基本的な使い方

jqのコマンドは、JSONデータをフィルタリングするための「フィルター」と呼ばれる式で構成されます。ここでは、最低限これだけ知れば使える基本コマンドを3〜5個紹介します。

まずは、簡単なJSONデータを用意しましょう。以下のコマンドでsample.jsonファイルを作成します。

cat << 'EOF' > sample.json
{
  "name": "Alice",
  "age": 30,
  "isStudent": false,
  "courses": [
    {"title": "Math", "score": 90},
    {"title": "Science", "score": 85},
    {"title": "History", "score": 78}
  ],
  "address": {
    "city": "Tokyo",
    "zip": "100-0001"
  }
}
EOF

1. JSON全体を表示・整形する (.)

最も基本的なフィルターは.(ドット)です。これは入力JSON全体を意味し、通常は整形された形式で出力されます。

cat sample.json | jq .

出力例:

{
  "name": "Alice",
  "age": 30,
  "isStudent": false,
  "courses": [
    {
      "title": "Math",
      "score": 90
    },
    {
      "title": "Science",
      "score": 85
    },
    {
      "title": "History",
      "score": 78
    }
  ],
  "address": {
    "city": "Tokyo",
    "zip": "100-0001"
  }
}

2. 特定のキーの値を取得する (.key)

JSONオブジェクトから特定のキーの値を取得するには、.の後にキー名を続けます。

cat sample.json | jq .name

出力例:

"Alice"

ネストされた(入れ子になった)キーの値を取得するには、ドットでつないでパスを指定します。

cat sample.json | jq .address.city

出力例:

"Tokyo"

3. 配列の要素にアクセスする (.array[], .array[index])

JSON配列から特定の要素や、すべての要素を抽出できます。

配列の最初の要素(インデックスは0から始まります)を取得する例です。

cat sample.json | jq .courses[0]

出力例:

{
  "title": "Math",
  "score": 90
}

配列のすべての要素に対して操作を行う場合は、[]を使用します。これは配列内の各要素を個別の出力ストリームとして扱います。

例えば、すべてのコースのタイトルを取得する例です。

cat sample.json | jq '.courses[].title'

出力例:

"Math"
"Science"
"History"

4. 複数のフィルターを組み合わせる (|)

|(パイプ)を使うと、複数のフィルターを連結し、前のフィルターの出力を次のフィルターの入力として渡せます。これにより、複雑なデータ変換が可能です。

例えば、すべてのコースのタイトルを取得し、それぞれに「Course」という文字列を追加する例です。

cat sample.json | jq '.courses[].title | . + " Course"'

出力例:

"Math Course"
"Science Course"
"History Course"

5. オブジェクトのキーを一覧表示する (keys)

JSONオブジェクトのトップレベルのキー(フィールド名)をリストとして取得できます。

cat sample.json | jq keys

出力例:

[
  "name",
  "age",
  "isStudent",
  "courses",
  "address"
]

これらの基本的なコマンドを組み合わせることで、多くのJSON操作が可能になります。

便利な使い方・応用例 3選

jqは、基本的な抽出だけでなく、データのフィルタリング、変換、整形など、様々な応用が可能です。ここでは、実際の開発シーンで役立つ応用例を3つ紹介します。

まずは、以下のJSONデータを用意しましょう。これは複数のユーザー情報を含む配列です。

cat << 'EOF' > users.json
[
  {
    "id": 101,
    "name": "Alice",
    "email": "alice@example.com",
    "isActive": true,
    "roles": ["admin", "editor"]
  },
  {
    "id": 102,
    "name": "Bob",
    "email": "bob@example.com",
    "isActive": false,
    "roles": ["viewer"]
  },
  {
    "id": 103,
    "name": "Charlie",
    "email": "charlie@example.com",
    "isActive": true,
    "roles": ["editor"]
  },
  {
    "id": 104,
    "name": "David",
    "email": null,
    "isActive": false,
    "roles": []
  }
]
EOF

1. 特定の条件を満たすオブジェクトをフィルタリングする (select())

select()関数を使うと、配列の中から特定の条件を満たすオブジェクトだけを抽出できます。これは、ログ解析やAPIレスポンスのデバッグで非常に役立ちます。

例えば、isActivetrueのユーザー、つまりアクティブなユーザーだけを抽出したい場合です。

cat users.json | jq '.[] | select(.isActive == true)'

出力例:

{
  "id": 101,
  "name": "Alice",
  "email": "alice@example.com",
  "isActive": true,
  "roles": ["admin", "editor"]
}
{
  "id": 103,
  "name": "Charlie",
  "email": "charlie@example.com",
  "isActive": true,
  "roles": ["editor"]
}

さらに、「rolesadminが含まれるユーザー」を抽出することも可能です。

cat users.json | jq '.[] | select(.roles[] == "admin")'

出力例:

{
  "id": 101,
  "name": "Alice",
  "email": "alice@example.com",
  "isActive": true,
  "roles": ["admin", "editor"]
}

2. データを変換し、新しい構造のJSONを作成する (map(), {})

入力JSONから必要なフィールドだけを選び、新しい構造のJSONオブジェクトや配列を生成できます。これは、データのレポート作成や、特定の形式への変換に便利です。

例えば、すべてのユーザーについて、idname、そしてisActiveの状態を示すstatusフィールド("Active"または"Inactive")だけを含む新しい配列を作成したい場合です。

cat users.json | jq 'map({id: .id, name: .name, status: (if .isActive then "Active" else "Inactive" end)})'

出力例:

[
  {
    "id": 101,
    "name": "Alice",
    "status": "Active"
  },
  {
    "id": 102,
    "name": "Bob",
    "status": "Inactive"
  },
  {
    "id": 103,
    "name": "Charlie",
    "status": "Active"
  },
  {
    "id": 104,
    "name": "David",
    "status": "Inactive"
  }
]

3. フィールドを削除する (del())

JSONオブジェクトから不要なフィールドを削除できます。これは、個人情報保護の観点から特定のフィールドをマスクしたり、データ量を減らしたりする際に有用です。

例えば、すべてのユーザーオブジェクトからemailフィールドを削除したい場合です。

cat users.json | jq 'map(del(.email))'

出力例:

[
  {
    "id": 101,
    "name": "Alice",
    "isActive": true,
    "roles": ["admin", "editor"]
  },
  {
    "id": 102,
    "name": "Bob",
    "isActive": false,
    "roles": ["viewer"]
  },
  {
    "id": 103,
    "name": "Charlie",
    "isActive": true,
    "roles": ["editor"]
  },
  {
    "id": 104,
    "name": "David",
    "isActive": false,
    "roles": []
  }
]

これらの応用例を参考に、あなたの開発ワークフローにjqを組み込んでみてください。

他ツールとの組み合わせ

jqは単体でも強力ですが、他のCLIツールと組み合わせることで、その真価をさらに発揮します。パイプラインを通じて、様々なツールの良いとこ取りができます。

curlと組み合わせてAPIレスポンスを整形

Web APIからのJSONレスポンスを直接jqに渡し、必要な情報だけを抽出・整形できます。デバッグやスクリプトでのデータ取得に非常に便利です。

例えば、GitHub APIからjqリポジトリの情報を取得し、リポジトリ名、スター数、説明だけを表示する例です。

curl -s https://api.github.com/repos/jqlang/jq | jq '{name: .full_name, stars: .stargazers_count, description: .description}'

-sオプションはcurlの進捗表示を抑制します。

出力例:

{
  "name": "jqlang/jq",
  "stars": 28000,
  "description": "Command-line JSON processor"
}

grepと組み合わせてJSONログを解析

大量のJSON形式のログファイルから、特定のキーワードを含む行をgrepで抽出し、さらにjqでそのJSONデータを整形・分析できます。

例えば、以下のようなログファイルapp.logがあるとします。

cat << 'EOF' > app.log
{"timestamp":"2023-10-27T10:00:00Z","level":"info","message":"User logged in","user_id":101}
{"timestamp":"2023-10-27T10:01:00Z","level":"error","message":"Database connection failed","error_code":500}
{"timestamp":"2023-10-27T10:02:00Z","level":"info","message":"User logged out","user_id":101}
{"timestamp":"2023-10-27T10:03:00Z","level":"warn","message":"API rate limit exceeded","service":"github"}
EOF

このログから「Database connection failed」というエラーメッセージを含む行をgrepで探し、その行のtimestamperror_codejqで抽出する例です。

grep "Database connection failed" app.log | jq '{time: .timestamp, code: .error_code}'

出力例:

{
  "time": "2023-10-27T10:01:00Z",
  "code": 500
}

findxargsと組み合わせて複数のJSONファイルを処理

複数のディレクトリに散らばったJSONファイルに対して、一括でjq処理を行いたい場合に役立ちます。

例えば、dataディレクトリ内に複数のJSONファイルがあり、それぞれのファイルからidフィールドを抽出したいとします。

mkdir -p data
echo '{"id":1, "name":"Item A"}' > data/item1.json
echo '{"id":2, "name":"Item B"}' > data/item2.json
echo '{"id":3, "name":"Item C"}' > data/item3.json

find data -name "*.json" | xargs -I {} sh -c 'echo "File: {}"; cat {} | jq ".id"'

xargs -I {}は、findの出力(ファイルパス)を{}に置き換え、指定したコマンドを実行します。

出力例:

File: data/item1.json
1
File: data/item2.json
2
File: data/item3.json
3

これらの組み合わせは、シェルスクリプトや自動化ツールの中で、JSONデータを柔軟に扱うための強力な基盤となります。

よくある設定・カスタマイズ

jq自体には、dotfilesのような設定ファイルはありません。しかし、シェル(BashやZshなど)のエイリアスや関数を定義することで、jqの利用体験を大幅にカスタマイズし、効率を高められます。

.bashrc.zshrcといったシェル設定ファイルに記述することで、これらのカスタマイズを永続化できます。

1. よく使うjqコマンドをエイリアス化する

頻繁に使うjqコマンドに短い別名を付けることで、入力の手間を省きます。

JSONを整形して表示するエイリアス

jq .はJSON整形に最もよく使われるコマンドです。これをjpp(JSON Pretty Print)などのエイリアスにできます。

# ~/.bashrc または ~/.zshrc に追加
alias jpp='jq .'

使用例:

cat sample.json | jpp

JSONのキー一覧を表示するエイリアス

オブジェクトのキーを一覧表示するjq keysも、よく使われます。

# ~/.bashrc または ~/.zshrc に追加
alias jks='jq keys'

使用例:

cat sample.json | jks

2. jqを使ったシェル関数を定義する

より複雑なjqの操作や、他のツールとの組み合わせを頻繁に行う場合は、シェル関数として定義すると便利です。これにより、引数を受け取って動的にjqフィルターを生成したり、複数のコマンドをまとめて実行したりできます。

GitHubリポジトリ情報を整形して表示する関数

特定のAPIから情報を取得し、必要なデータだけを抽出して整形する関数を作成する例です。

# ~/.bashrc または ~/.zshrc に追加
jq_gh_repo() {
    if [ -z "$1" ]; then
        echo "Usage: jq_gh_repo <owner/repo>"
        return 1
    fi
    # curlでGitHub APIからリポジトリ情報を取得し、jqで整形
    curl -s "https://api.github.com/repos/$1" | \
    jq '{
        name: .full_name,
        description: .description,
        stars: .stargazers_count,
        forks: .forks_count,
        url: .html_url,
        license: .license.spdx_id // "No License"
    }'
}

この関数は、リポジトリのオーナーと名前(例: jqlang/jq)を引数として受け取り、整形されたJSONを出力します。//は、左辺がnullの場合に右辺のデフォルト値を適用する演算子です。

使用例:

jq_gh_repo jqlang/jq

出力例:

{
  "name": "jqlang/jq",
  "description": "Command-line JSON processor",
  "stars": 28000,
  "forks": 1500,
  "url": "https://github.com/jqlang/jq",
  "license": "MIT"
}

これらのエイリアスや関数を.bashrc.zshrcに追加したら、source ~/.bashrcまたはsource ~/.zshrcを実行して設定を反映させてください。これにより、コマンドラインからこれらの便利な機能を使えるようになります。

今日からできる実行プラン

jqの学習と活用を今日から始めるための3ステップを紹介します。

ステップ1: jqをインストールする

まずは、お使いの環境にjqをインストールしましょう。本記事の「インストール方法」セクションを参考に、最も手軽な方法を選んでください。

インストール後、以下のコマンドを実行してバージョンが表示されれば成功です。

jq --version

ステップ2: 手元のJSONデータをjq .で整形してみる

インストールが完了したら、実際にjqを使ってみましょう。手元にあるJSONファイル(例えば、APIのレスポンス、設定ファイル、package.jsonなど)をjq .にパイプで渡して整形してみてください。

cat your_file.json | jq .

もし手元にファイルがない場合は、以下のコマンドでサンプルJSONを作成して試せます。

echo '{"name": "jq", "version": "1.7.1"}' | jq .

整形されたJSONを見るだけでも、jqの便利さを実感できるでしょう。

ステップ3: 特定のキーの抽出やフィルタリングを試す

ステップ2で整形したJSONデータに対して、さらに踏み込んだ操作を試してみましょう。

  • 特定のキーの値を取得:
    cat your_file.json | jq .key_name
    
  • ネストされたキーの値を取得:
    cat your_file.json | jq .parent_key.child_key
    
  • 配列の要素を抽出:
    cat your_file.json | jq .array_key[]
    

本記事の「基本的な使い方」や「便利な使い方・応用例」で紹介したコマンドを参考に、色々なフィルターを試してみてください。

jqには、他にも多くの強力な機能があります。より深く学びたい場合は、jq 公式ドキュメントTry jq Onlineで実際に試しながら学習を進めるのがおすすめです。

これらのステップを通じて、jqがあなたの開発ワークフローにどれほど価値をもたらすか、きっと実感できるはずです。

参考文献

広告

-AI