LoginSignup
19
7

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-12-20

この記事は、ニフティグループ 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を効率よく扱う方法を学べたことは、自分にとって大きな財産になったと思います。
以上、閲覧していただきありがとうございました!!

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

19
7
3

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
  3. You can use dark theme
What you can do with signing up
19
7