jqで簡単JSON加工

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

jqとは

jqとは、コマンドラインからJSONを操作することができるツールです。
curlコマンドとかでJSONレスポンスを取得した場合、データ量が多いと非常に見づらいデータがかえってきたりして困ります。
ためしにtwitterの検索結果を表示してみると、こんな感じになります。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true'                      
{"completed_in":0.022,"max_id":331584529343062017,"max_id_str":"331584529343062017","next_page":"
</br>page=2&max_id=331584529343062017&q=classmethod&rpp=2&include_entities=1","page":1,"query":"classmethod",
"refresh_url":"?since_id=331584529343062017&q=classmethod&include_entities=1","results":[{"created_at":"Tue, 07 May 2013 01:41:26 +0000","entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/nQNxfAzzDM","expanded_url":"http:\/\/htn.to\/h1B4H9LUA7","display_url":
"htn.to\/h1B4H9LUA7","indices":[46,68]}],"user_mentions":</br>[]},"from_user":"shigeo_t","from_user_id":65307990,"from_user_id_str":"65307990","from_user_name":
"shigeo_t","geo":null,"id":331584529343062017,"id_str":"331584529343062017","iso_language_code":"ja","metadata"
・
・

何が何やら見難いです。日本語もエスケープされてるし。
こういったJSON文字列をきれいに整形たり必要データだけ抽出したりできるツールが、今回紹介するjqです。

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.5
  • Homebrew : 0.9.4

homebrewでjqをインストールしてもいいのですが、私の場合はbisonのバージョンか何かの問題でインストールできませんでした。
brew install jqでインストールできない場合、ここにはバイナリも置いてあるので、それをダウンロードしてパスの通った場所におきましょう。

jqを使ってみよう

jqは、jq [オプション] <フィルタ> [ファイル]としてJSONファイルを整形するか、curl等で取得したJSON文字列をパイプでつなげて使います。
まずは、さきほど取得してみたtwitter検索結果を見やすく表示してみましょう。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true' | jq "."
・
・
(ry

インデントも日本語表示もできているし、色分けもされており、とても見やすくなっています。

jqは単にきれいに表示するだけでなく、結果から属性や要素を選択して表示することもできます。
.<要素名>で、指定した要素だけを取得することができます。次の例では、results要素のtext属性だけを取得しています。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true' | jq ".results[].text"
"// SpotInstanceとJMeterを使って400万req/minの負荷試験を行う|クラスメソッド株式会社 開発ブログ http://t.co/6wgTM6S0XV"
"「非VPCが許されるのは小学生まで」らしい 早く中学生になりたい / “Amazon VPCを使ったミニマム構成のサーバ環境を構築する | クラスメソッド開発ブログ” http://t.co/UA2IMNid04"

指定する要素が配列の場合、インデックスを指定すれば、それだけを取得できます。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true' | jq ".results[0]"
・
・
(ry

,で複数の要素を選択できますし、結果のJSONにフィールド名をつけて表示させることもできます。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true'|jq ".results[] | {from_user, text, urls: [.entities.urls[].url]}"
・
・
(ry

また、ここにいろいろと書いてありますが、関数を使用して結果を加工することも可能です。

% curl 'http://search.twitter.com/search.json?q=classmethod&rpp=2&include_entities=true'|jq ".results[] | keys"
・
・
(ry

それ以外にも、ソートしたりif-elseで分岐させたり等、いろいろなことができます。

参考サイトなど