LoginSignup
7

More than 1 year has passed since last update.

posted at

updated at

「jqめちゃくちゃ便利じゃん😂」と感動することが多いので使い方を調べた

この記事は、ニフティグループ Advent Calendar 2021 21日目の記事です。

はじめに

皆さんはjqを活用していますでしょうか?
私は、業務の中でJSONデータを扱うことが多く、巨大なJSONデータの一部を抽出する時や整形して企画チームのメンバーに共有する時などにお世話になっております。
使うたびに、「そんなこと出来るの!?すげえ😂」と感動していました。

そこで、アドベントカレンダーの執筆を機会に「自分用のメモを作ってしまおう😚」と考え記事を書くことにしました。

使う頻度が高そうだと判断したもののみ抜粋しました。その点をご了承くださいませ。

環境

  • macOS Catalina version 10.15.6
  • jq version 1.6

以下の内容は公式ドキュメントを参考にしています。詳しく知りたい方はこちらを参考にしてください。
jq

インストール方法

brewで入れることができます。

$ brew install jq

jq — Homebrew Formulae

macOS以外の方は以下のページを参考にしてください。

Download jq

テスト用データ

以下のサンプルデータを使用します。

user.json
{
    "name": "Tanaka",
    "age": 25,
    "address": {
        "state": "tokyo",
        "city": "shinjuku"
    }
}
users.json
[
    {
        "name": "Tanaka",
        "age": 25,
        "address": {
            "state": "tokyo",
            "city": "shinjuku"
        }
    },
    {
        "name": "Suzuki",
        "age": 30,
        "address": {
            "state": "chiba",
            "city": "funabashi"
        }
    }
]

フォーマット

jqはデフォルトでJSONをフォーマットしてくれます。
以下の記述で、フォーマットのみを行います。

$ cat user.json | jq .
{
  "name": "Tanaka",
  "age": 25,
  "address": {
      "state": "tokyo",
      "city": "shinjuku"
  }
}

基本的な絞り込み

特定のキーの値のみ取得する

以下の記述で、特定のキーの値のみを取得できます。
ユーザのnameを取得してみます。

$ cat user.json | jq '.name'
"Tanaka"

複数のキーをドットで連結することにより、ネストされた値を取得することができます。
addressのstateを取得してみます。

$ cat user.json | jq '.address.state'
"tokyo"

配列についてはこの後解説しますが、要素ごとの値も取得することができます。
|(パイプ)区切りにすることで、左側の処理から実行されます。
配列を取得した後に配列ごとにageを取得してみます。

$ cat users.json | jq '.[] | .age'
25
30

キーも残す場合は以下のように記述します。

$ cat users.json | jq '.[] | {name, age}'
{
  "name": "Tanaka",
  "age": 25
}
{
  "name": "Suzuki",
  "age": 30
}

複数のキーの値を取得する

条件がカンマで区切られている場合は、同じ入力が両方に行われそれぞれの結果が順番に出力されます。
今回であれば、

  1. ageを取得
  2. addressの中のstateを取得

の順番で処理されています。

$ cat user.json | jq '.age,.address.state'
25
"tokyo"

配列を取得する

以下の記述で、配列を取得できます。
全ユーザの情報を取得してみます。

$ cat users.json | jq '.[]'
{
  "name": "Tanaka",
  "age": 25,
  "address": {
    "state": "tokyo",
    "city": "shinjuku"
  }
}
{
  "name": "Suzuki",
  "age": 30,
  "address": {
    "state": "chiba",
    "city": "funabashi"
  }
}

配列の特定の要素のみ取得する

インデックスを指定することで、配列の一部を取得することができます。
2人目のユーザ情報のみ取得してみます。

$ cat users.json | jq '.[1]'
{
  "name": "Suzuki",
  "age": 30,
  "address": {
    "state": "chiba",
    "city": "funabashi"
  }
}

配列の構築

以下の記述で配列を構築できます。
ユーザごとのaddressを取得し、配列を構築してみます。

$ cat users.json | jq ['.[] | .address']
[
  {
    "state": "tokyo",
    "city": "shinjuku"
  },
  {
    "state": "chiba",
    "city": "funabashi"
  }
]

オブジェクトの構築

以下の記述でオブジェクトを構築できます。
ユーザごとのnameを取得し、namesというキーの値に設定してみます。

$ cat users.json | jq '{"names": [.[] | .name]}'
{
  "names": [
    "Tanaka",
    "Suzuki"
  ]
}

計算

四則演算

四則演算は一通り実行できます。
ユーザの年齢に50加えてみます。

$ cat user.json | jq '.age+50'
75

配列の合計を取得する

配列に対して、 add関数 を使用することで合計値を取得することができます。
ageの合計を取得してみます。

$ cat users.json | jq '[.[] | .age] | add'
55

配列の平均を取得する

length関数については後で解説しますが、配列の長さで割ることで配列の平均を取得することができます。
ageの平均を取得してみます。

$ cat users.json | jq '[.[] | .age] | add / length'
27.5

その他の組み込み関数

長さを取得する

length関数 を使用することで、長さを取得することができます。配列の場合は要素数が取得できます。
ユーザの数を取得してみます。

$ cat users.json | jq '.| length'
2

キーの一覧を取得する

keys関数 を使用することで、オブジェクトのキーを一覧で取得できます。

$ cat user.json | jq 'keys'
[
  "address",
  "age",
  "name"
]

特定のキーを削除する

del関数 を使用することで、キーの一部を削除することができます。
addressを削除してみます。

$ cat user.json | jq 'del(.address)'
{
  "name": "Tanaka",
  "age": 25
}

配列に適用することも可能です。

$ cat users.json | jq '.[] | del(.address)'
{
  "name": "Tanaka",
  "age": 25
}
{
  "name": "Suzuki",
  "age": 30
}

条件で絞り込んで取得する

select関数 を使用することで、条件で絞り込んで取得することができます。
ageが25のユーザのみ取得してみます。

$ cat users.json | jq '.[] | select(.age == 25)'
{
  "name": "Tanaka",
  "age": 25,
  "address": {
    "state": "tokyo",
    "city": "shinjuku"
  }
}

ソート

sort_by関数を利用することで、特定の値をもとに昇順ソートできます。
ageをもとに昇順ソートしてみます。

$ cat users.json | jq 'sort_by(.age)'
[
  {
    "name": "Tanaka",
    "age": 25,
    "address": {
      "state": "tokyo",
      "city": "shinjuku"
    }
  },
  {
    "name": "Suzuki",
    "age": 30,
    "address": {
      "state": "chiba",
      "city": "funabashi"
    }
  }
]

降順ソートについては、 reverse関数を使用することで実現できます。

$cat users.json | jq 'sort_by(.age) | reverse'
[
  {
    "name": "Suzuki",
    "age": 30,
    "address": {
      "state": "chiba",
      "city": "funabashi"
    }
  },
  {
    "name": "Tanaka",
    "age": 25,
    "address": {
      "state": "tokyo",
      "city": "shinjuku"
    }
  }
]

CSV化

@csvを利用することで、jsonをcsvに変換することができます。
入力するjsonは配列である必要があります。
ユーザ情報をcsvとして取得してみます。

$ cat users.json | jq -r '.[] | [.name, .age, .address.state + " " + .address.city]| @csv'
"Tanaka",25,"tokyo shinjuku"
"Suzuki",30,"chiba funabashi"

最後に

今回はjqの使い方を学びました。エンジニアである以上、JSONとは切っても切り離せない関係です。
そんなJSONを効率よく扱う方法を学べたことは、自分にとって大きな財産になったと思います。
以上、閲覧していただきありがとうございました!!

皆さんのお気に入りの使い方がありましたら、ぜひコメントしていってください!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7