jqコマンドの基本的な使い方と便利なオプションまとめ | 瀬戸内の雲のように

jqコマンドの基本的な使い方と便利なオプションまとめ

Posted: 2018-01-22


スポンサーリンク

目次

背景

最近API関連の業務に携わるようになり、jsonを扱うことが増えました。
APIのテストを行う場合、windowsではpostmanなどのツールがあるのですが、私はスクリプト化しやすいのでlinux上でcurlコマンドを使います。そこで結果を整形して見やすくするためにjqを一緒に使うのですが、いろいろなオプションを調べましたのでまとめておきます。

関連記事: 【jqコマンド】selectで(23) Failed writing bodyというエラーが出る

大前提: jqコマンドとは

linuxのコマンドライン上でjson形式の文字列を整形したり加工したりするツールです。
最も基本的な整形はこんな感じです。

$ echo '{"name": "ken"}' | jq '.'
{
  "name": "ken"
}

(実際にはカラーで表示されます)

といった感じで、複雑な構造のjsonも見やすく表示してくれます。

jqのインストール(centos7)

jqは基本的にはデフォルトではインストールされてないので、yumでインストールします。

# yum install jq
================================================================================
 Package            Arch            Version                 Repository     Size
================================================================================
Installing:
 jq                 x86_64          1.5-1.el7               epel          153 k
Installing for dependencies:
 oniguruma          x86_64          5.9.5-3.el7             epel          129 k

Transaction Summary
================================================================================
Install  1 Package (+1 Dependent package)

Total download size: 282 k
Installed size: 906 k
Is this ok [y/d/N]: y
Downloading packages:
(1/2): jq-1.5-1.el7.x86_64.rpm                             | 153 kB   00:15
(2/2): oniguruma-5.9.5-3.el7.x86_64.rpm                    | 129 kB   00:15
--------------------------------------------------------------------------------
Total                                              9.4 kB/s | 282 kB  00:30
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : oniguruma-5.9.5-3.el7.x86_64                                 1/2
  Installing : jq-1.5-1.el7.x86_64                                          2/2
  Verifying  : oniguruma-5.9.5-3.el7.x86_64                                 1/2
  Verifying  : jq-1.5-1.el7.x86_64                                          2/2

Installed:
  jq.x86_64 0:1.5-1.el7

Dependency Installed:
  oniguruma.x86_64 0:5.9.5-3.el7

Complete!

一発です。

 

基本的な使い方

さて、ここからが本題です。まずは基本的な使い方から。

起動方法

linuxのコマンドとして使います。標準出力からパイプで渡します。

echo '{"name": "ken", "age": "30"}' | jq '.'

結果は以下の通り。

{
  "name": "ken",
  "age": "30"
}

 
ファイルから読み込む場合は以下の通り。

cat users.json | jq '.'

結果は以下の通り

{
  "name": "ken",
  "age": "30"
}

とても簡単です。

 

要素の取り出し方

jsonの中には基本的に

  • 配列[]
  • ハッシュ{} ※keyとvalueの組み合わせ

が入っています。それぞれの取り出し方を以下のようなjsonの例で説明します。

{
  "users": [
    {
      "name": "ken",
      "age": 30
    },
    {
      "name": "taro",
      "age": 25
    }
  ]
}

 
まず先頭の要素であるusersの中身は.usersで取り出せます。

cat users.json | jq '.users'

結果は以下の通り。

# cat users.json | jq '.users'
[
  {
    "name": "ken",
    "age": 30
  },
  {
    "name": "taro",
    "age": 25
  }
]

usersの中身は配列なので、ちゃんと配列が返ってきています。

 
次にこの配列の中身を取り出します。まずシンプルに[]を取る場合は以下のようにします。

cat users.json | jq '.users[]'

結果は以下の通り。

{
  "name": "ken",
  "age": 30
},
{
  "name": "taro",
  "age": 25
}

出力結果から先頭の'[' と 末尾の']' がなくなっていることがわかります。

 
また、1つ目の要素だけを取り出す場合は以下のようにします。

cat users.json | jq '.users[0]'
{
  "name": "ken",
  "age": 30
}

 
さらに、この中からname要素だけを取得します。

cat users.json | jq '.users[0].name'

結果は以下のようになります。

"ken"

 

要素の取り出し方まとめ

このように、要素の順に処理を書いていけば最終的に値を取り出すことができます。
覚えておくべきことをまとめると、以下の通りです。

  • 最初の要素には必ず"."を付ける
  • 先頭が "{"の場合には .キー名 で取り出せる
  • 先頭が "["の場合には [] で配列全体を取り出せる。
  • 先頭が "["の場合に、配列の要素を一部だけ取り出したい場合は[数値]で取り出せる。

これだけ覚えていれば、とりあえず最後の要素まで取り出すことができると思います。

 

複数の条件

上記のように1コマンドだけを実行することもできますが、複数の条件を順番に実行することもできます。
つまり以下のようなことです。

cat users.json | jq '.users | .[0] | .name'

これで先程のコマンドと同じ結果となります。

# cat users.json | jq '.users | .[0] | .name'
"ken"

このように、jqコマンドの中でパイプでつなぐことで複数回のコマンド実行できます。
(=1回目の実行結果を2回目の入力として使えるという理解)

 

便利なオプション

続いては少し応用編ということで便利なオプションについて説明していきます。
使うjsonは先程と同じです。

1. 値を検索する(select)

特定のキーの値を元に要素を検索することができます。

$ cat users.json | jq '.users[] | select(.name == "ken")'

これで、namekenのuserを検索することができます。

$ cat users.json | jq '.users[] | select(.name == "ken")'
{
  "name": "ken",
  "age": 30
}

ここで注意なのは、最終的に表示される内容は入力値のパスとなること。
つまり、以下のコマンドだと意図通りには動きません。

$ cat users.json | jq 'select(.users[].name == "ken")'
{
  "users": [
    {
      "name": "ken",
      "age": 30
    },
    {
      "name": "taro",
      "age": 25
    }
  ]
}

入力の時点で検索結果として欲しいパスを指定しておく(上記の例では".users[]")ことが必要となります。

2. 値をあいまい検索する(like検索)

文字列の検索をする時には、「◯◯を含む」のようにあいまい検索をしたいときがあります。
その場合は以下のように、select ( .キー名 | contains("文字列")) というコマンドで行います。

cat users.json | jq '.users[] | select( .name | contains("e"))'

このコマンドで、nameの中に"e"を含むuserを検索するという意味になります。
結果は以下の通りです。

$ cat users.json | jq '.users[] | select( .name | contains("ken"))'
{
  "name": "ken",
  "age": 30
}

3. 値を修正する

次に、出力する値を修正する方法です。
値を修正とは、以下のように入力値に対して何かしらの修正を加えることを言っております。

 
文字列を追記する

$ cat users.json | jq '.users[0] | .name += " is my name"'
{
  "name": "ken is my name",
  "age": 30
}

 
文字列を置換する

$ cat users.json | jq '.users[0] | .name = "KEN"'
{
  "name": "KEN",
  "age": 30
}

 
数値計算をする

$ cat users.json | jq '.users[0] | .age + 1'
31

4. 必要な情報を抽出しjsonを再構築する

出力結果から必要な情報だけ抽出したものを再度jsonとして構築し、出力する方法です。
例えば、以下のようなjsonがあった時に、

$ cat services.json
{
  "services": {
    "id": "12345",
    "name": "great-service",
    "company": {
      "id": "00001",
      "name": "abc-company",
      "place": "japan"
    }
  }
}

services直下のidとcompany直下のidだけを抽出したい場合、以下のコマンドで可能です。

cat services.json | jq '.services | {service_id: .id , company_id: .company.id}'

すると以下のように出力されます

$ cat services.json | jq '.services | {service_id: .id , company_id: .company.id}'
{
  "service_id": "12345",
  "company_id": "00001"
}

このようにjqコマンド内でパイプで渡した出力結果に含まれる要素(上の例では.id.company.id)を値としてjsonを再構築して表示させることができます。

 

5. 表示からダブルクォーテーションを取る

これはシンプルです。jqコマンドに -rオプションを付ければOKです。

$ cat users.json | jq -r '.users[0].name'
ken

まとめ

このようにjqコマンドを使うと非常に簡単にjsonオブジェクトを扱うことができます。
これからの時代、jqコマンドはgrepやsed,awkコマンドのようにlinuxの標準的なコマンドになっていくのではと思います。


スポンサーリンク




コメント一覧


コメントを投稿する


お名前


コメント内容





TOP back