JSONを扱いやすくするコマンド(jq, gron)のメモ

JSONを扱いやすくするコマンドのjqgronのメモ。

jq コマンド

jq コマンドはJSON向けのawkのようなコマンド。

インストール方法(on Mac

$ brew install jq

使い方

パイプで渡されたJSONデータにフィルターをかけることができる。

GitHub APIを使ってリポジトリ名を列挙する例

$ curl -s `curl -s https://api.github.com/users/tkmru | jq -r .repos_url`  | jq '.[].name'
"anarchy_proof"
"anti_debugging_test"
"aoj"
"awesome-linux-rootkits"
"a_and_d_web_nara"
"biwx"
...
"isucon4-qualifier-mokumoku"
"isucon6-qual-practice"
"isucon_pixv"
"ldap3"
"linux-driver-playground"
"linux-insides"
"linux-insides-ja"
"machine-learning-playground"

GitHub APIを使って最新コミット情報を取って来る例

$ curl 'https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1' | jq '.[0]'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7328  100  7328    0     0   9488      0 --:--:-- --:--:-- --:--:--  9492
{
  "sha": "c764b1baad95cb18cec14a1b7f84b460b6f0b3cc",
  "commit": {
    "author": {
      "name": "tkmru",
      "email": "i.am.tkmru@gmail.com",
      "date": "2018-04-10T14:33:34Z"
    },
    "committer": {
      "name": "tkmru",
      "email": "i.am.tkmru@gmail.com",
      "date": "2018-04-10T14:33:34Z"
    },
    "message": "Merge branch 'master' of github.com:tkmru/dotfiles",
  ...
  "parents": [
    {
      "sha": "495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5",
      "url": "https://api.github.com/repos/tkmru/dotfiles/commits/495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5",
      "html_url": "https://github.com/tkmru/dotfiles/commit/495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5"
    },
    {
      "sha": "7f0f75610a2856c6cc97a3b1d949f5a4345a53df",
      "url": "https://api.github.com/repos/tkmru/dotfiles/commits/7f0f75610a2856c6cc97a3b1d949f5a4345a53df",
      "html_url": "https://github.com/tkmru/dotfiles/commit/7f0f75610a2856c6cc97a3b1d949f5a4345a53df"
    }
  ]
}

GitHub APIを使ってコミットメッセージ、名前を列挙する例

$ curl 'https://api.github.com/repos/tkmru/dotfiles/commits?per_page=2' | jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7328  100  7328    0     0   9382      0 --:--:-- --:--:-- --:--:--  9382
[
  {
    "message": "Merge branch 'master' of github.com:tkmru/dotfiles",
    "name": "tkmru"
  },
  {
    "message": "add ungron",
    "name": "tkmru"
  }
]

gron コマンド

JSONgrepしやすい形式、JavaScriptで扱える形式に変換してくれるコマンド。 Golang製。

インストール方法(on Mac

$ brew install gron

使い方

URLもしくはJSONファイルを指定すると変換してくれる。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1"
json = [];
json[0] = {};
json[0].author = {};
json[0].author.avatar_url = "https://avatars3.githubusercontent.com/u/1628214?v=4";
json[0].author.events_url = "https://api.github.com/users/tkmru/events{/privacy}";
json[0].author.followers_url = "https://api.github.com/users/tkmru/followers";
json[0].author.following_url = "https://api.github.com/users/tkmru/following{/other_user}";
....
json[0].parents[1].html_url = "https://github.com/tkmru/dotfiles/commit/7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].parents[1].sha = "7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].parents[1].url = "https://api.github.com/repos/tkmru/dotfiles/commits/7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].sha = "c764b1baad95cb18cec14a1b7f84b460b6f0b3cc";
json[0].url = "https://api.github.com/repos/tkmru/dotfiles/commits/c764b1baad95cb18cec14a1b7f84b460b6f0b3cc";

これによってgrepしやすくなる。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1" | grep commit.message
json[0].commit.message = "Merge branch 'master' of github.com:tkmru/dotfiles";

ungron

gronの出力結果をJSONに戻すには--ungronオプションを付ければいい。 以下のようにaliasを設定するよう、READMEで推奨されている。

alias norg="gron --ungron"
alias ungron="gron --ungron"

grepした結果をJSONで欲しいときに使える。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1" | grep commit.message | ungron
[
  {
    "commit": {
      "message": "Merge branch 'master' of github.com:tkmru/dotfiles"
    }
  }
]

diffもgronを使えば見やすい結果で取れる。

$ diff <(gron http://echo.jsontest.com/number/one) <(gron http://echo.jsontest.com/number/two)
2c2
< json.number = "one";
---
> json.number = "two";

JavaScriptから出力結果をさわる

出力されたテキストはJavaScriptのObjectとして扱える。

$ gron http://headers.jsontest.com/ > tmp.js
$ echo "console.log(json);" >> tmp.js
$ node tmp.js
{ Accept: 'application/json',
  Host: 'headers.jsontest.com',
  'User-Agent': 'gron/dev',
  'X-Cloud-Trace-Context': '0f152eb1d17dc08fd257b8b4383faaa6/9190834354357706108' }