jqのすゝめ

最近は何かデータをやり取りする際にAPIJSONでやり取りされることが多いですね。
データや仕様を確認するのに簡単なプログラムを書いたり、ブラウザの拡張機能を利用することを多いと思います。
今回は非常に簡単にJSONを扱えるjqコマンドについてご紹介します。

jqとは

JSONの集計や整形を簡単にできるコマンドです。
Linuxはもとより、WindowsMacでも動作します。

インストール

redhat系であれば、yumで管理されてます。

$ sudo yum -y install jq

Ubuntuにもありそうです。

$ sudo apt -y install jq

使い方

コマンドのヘルプに記載されているExample通り

[User@Host dev]$ echo '{"foo": 0}' | jq .
{
  "foo": 0
}

これだけだと良さが良くわからないので、TwitterAPIを用いて色々加工してみたいと思います。
弊社サービスのicottoのTwitterを取得してみます。
この先何度かデータ取得するため、コマンド化しておきます。
※V2を利用をしていましたが、現在プロジェクト登録しても無料枠で利用できない状況の様なのでV1.1を利用

getTweet

#!/bin/sh

# Setting
bearer_token="Developer Portalから取得したBearer Tokenを設定"
url="https://api.twitter.com/1.1/search/tweets.json"
query="from:icotto_official"
options="lang=ja&result_type=recent&count=3"

# Get Json
curl -s \
--header "Authorization: Bearer ${bearer_token}" \
--request GET "${url}?q=${query}&${options}"

オプションの補足
- lang: 言語
- result_type : popular(人気順), recent(最新順), mixed(混合)
- count : 取得件数
こちらに綺麗にまとまっています。

このまま実行すると結果は返ってきますが非常に見にくいです。

jqコマンドで整形すると非常に見やすくなります。

では特定の値だけを取ってみましょう。
statusesという配列の中からツイート内容である、textにアクセスするにはこのように書きます。

.statuses[].text
[User@Host dev]$ ./getTweet | jq '.statuses[].text'
"【熊本】観光拠点にぴったり♪熊本駅近のおすすめホテル8選\nhttps://t.co/JRvOxPu6gl\n #ホテル #駅近"
"飛騨高山◆おしゃれホテルに泊まろう!非日常が楽しめるホテル7選\nhttps://t.co/pzTcqQzsq0\n #ホテル #フォトジェニック #おしゃれ"
"愛媛の食をホテルの朝食でコンプリート♪松山市内の美味しいビュッフェ7選\nhttps://t.co/ovCcxPUqeQ\n #ホテル #朝食 #モーニング"

続いて複数の値を取得する場合はです。ID、ツイート内容、リンク先URLを取得してみます。
[]で囲むことで、配列で返してくれます。
見やすいです。

データとして1行の方が扱い易い場合も多いと思います。
そんな時はCSV形式でも出力可能です。

[User@Host dev]$ ./getTweet | jq '.statuses[] | [.id, .text, .entities.urls[0].expanded_url] | @csv'
"1668966577503608800,\"【熊本】観光拠点にぴったり♪熊本駅近のおすすめホテル8選\nhttps://t.co/JRvOxPu6gl\n #ホテル #駅近\",\"https://icotto.jp/presses/21537\""
"1668936383837388800,\"飛騨高山◆おしゃれホテルに泊まろう!非日常が楽しめるホテル7選\nhttps://t.co/pzTcqQzsq0\n #ホテル #フォトジェニック #おしゃれ\",\"https://icotto.jp/presses/21518\""
"1668906175042302000,\"愛媛の食をホテルの朝食でコンプリート♪松山市内の美味しいビュッフェ7選\nhttps://t.co/ovCcxPUqeQ\n #ホテル #朝食 #モーニング\",\"https://icotto.jp/presses/21536\""

特定のツイートを保存しておきたい場合などもあるかもと思います。
CSVで出力できるので、そんな時も便利です。
MySQLに結果を保存してみましょう。

まずはテーブル作成

create database twitter;
use twitter
CREATE TABLE tweets (
  id BIGINT NOT NULL,
  text TEXT,
  url VARCHAR(100),
  update_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

続いて先ほどのコマンドの結果をCSVファイルに保存します。

[User@Host dev]$ ./getTweet | jq -r '.statuses[] | [.id, .text, .entities.urls[0].expanded_url] | @csv' > tweets.csv
  • オプション説明
    -r : ダブルクォートを取り除く

LOAD DATA ステートメントを使い、CSVデータを登録します。

echo "
  load data local infile \"tweets.csv\"
  into table tweets
  fields terminated by ',' 
  optionally enclosed by '\"';" |
mysql --enable-local-infile -u user -p twitter

改行も含め綺麗に保存されています。

mysql> select * from tweets\G
*************************** 1. row ***************************
       id: 1668906175042302000
     text: 愛媛の食をホテルの朝食でコンプリート♪松山市内の美味しいビュッフェ7選
https://t.co/ovCcxPUqeQ
 #ホテル #朝食 #モーニング
      url: https://icotto.jp/presses/21536
update_at: 2023-06-15 10:36:57
*************************** 2. row ***************************
       id: 1668936383837388800
     text: 飛騨高山◆おしゃれホテルに泊まろう!非日常が楽しめるホテル7選
https://t.co/pzTcqQzsq0
 #ホテル #フォトジェニック #おしゃれ
      url: https://icotto.jp/presses/21518
update_at: 2023-06-15 10:36:57
*************************** 3. row ***************************
       id: 1668966577503608800
     text: 【熊本】観光拠点にぴったり♪熊本駅近のおすすめホテル8選
https://t.co/JRvOxPu6gl
 #ホテル #駅近
      url: https://icotto.jp/presses/21537
update_at: 2023-06-15 10:36:57
3 rows in set (0.00 sec)

もちろん、商用で動かすにはこれだけでは足りませんが、
JSONデータの中身の確認や一時的なデータを保存には、
さくっとjqコマンドが凄く便利に使えるというお話でした。

カカクコムでは共にサービスをつくる仲間を募集しています

カカクコムのエンジニアリングにご興味のある方は、是非こちらをご覧ください!


カカクコム採用サイト