jq, 强大的 shell 处理 json 的工具, 废话少说, 看几个例子.

使用 github 的 api 进行测试, 测试命令如下

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5'

[
  {
      "sha": "89682f6da75fcc896c00f1727f77ab325f3c1fab",
      "commit": {
            "author": {
                    "name": "xuxiao.xu",
                    "email": "xuxiao.xu@qunar.com",
                    "date": "2016-09-28T14:29:34Z"
                  },
            "committer": {
                    "name": "xuxiao.xu",
                    "email": "xuxiao.xu@qunar.com",
                    "date": "2016-09-28T14:29:34Z"
                  },
            "message": "fix setup",
            "tree": {
                    "sha": "dada86729b6d606f4beb5773a62258e52b4cb2f8",
                    "url": "https://api.github.com/repos/taizilongxu/douban.fm/git/trees/dada86729b6d606f4beb5773a62258e52b4cb2f8"
                  },
            "url": "https://api.github.com/repos/taizilongxu/douban.fm/git/commits/89682f6da75fcc896c00f1727f77ab325f3c1fab",
            "comment_count": 0
          },
      "url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/89682f6da75fcc896c00f1727f77ab325f3c1fab",
      "html_url": "https://github.com/taizilongxu/douban.fm/commit/89682f6da75fcc896c00f1727f77ab325f3c1fab",
      "comments_url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/89682f6da75fcc896c00f1727f77ab325f3c1fab/comments",
      "author": null,
      "committer": null,
      "parents": [
            {
                    "sha": "3155c45d6b8eb3c2cb08bf62922b33f19333ff0e",
                    "url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/3155c45d6b8eb3c2cb08bf62922b33f19333ff0e",
                    "html_url": "https://github.com/taizilongxu/douban.fm/commit/3155c45d6b8eb3c2cb08bf62922b33f19333ff0e"
                  }
          ]
    },
    ...
]

提出 array 里每个 sha 值

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[].sha'
 "89682f6da75fcc896c00f1727f77ab325f3c1fab"
 "3155c45d6b8eb3c2cb08bf62922b33f19333ff0e"
 "77bbc06a8fc0612816d26a534d8225fa888cb599"
 "45772fea9ff0a1f57ff293de448424091328f506"
 "dba4425fde4088afbf7879e311ec43c6527dbab8"

这时候只想提取出sha值但是带括号怎么办?

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[].sha' | sed s/\"//g  
89682f6da75fcc896c00f1727f77ab325f3c1fab
3155c45d6b8eb3c2cb08bf62922b33f19333ff0e
77bbc06a8fc0612816d26a534d8225fa888cb599
45772fea9ff0a1f57ff293de448424091328f506
dba4425fde4088afbf7879e311ec43c6527dbab8

但是这种也不能拿出来用, 怎么转化为json格式供给程序用?

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[].sha' | jq -s .
[
"89682f6da75fcc896c00f1727f77ab325f3c1fab",
"3155c45d6b8eb3c2cb08bf62922b33f19333ff0e",
"77bbc06a8fc0612816d26a534d8225fa888cb599",
"45772fea9ff0a1f57ff293de448424091328f506",
"dba4425fde4088afbf7879e311ec43c6527dbab8"
]

如果提取多种信息呢?

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[] | {sha: .sha, author: .author.login}' | jq -s . 
[
{
   "sha": "89682f6da75fcc896c00f1727f77ab325f3c1fab",
   "author": null
 },
{
   "sha": "3155c45d6b8eb3c2cb08bf62922b33f19333ff0e",
   "author": "taizilongxu"
 },
{
   "sha": "77bbc06a8fc0612816d26a534d8225fa888cb599",
   "author": "taizilongxu"
 },
{
   "sha": "45772fea9ff0a1f57ff293de448424091328f506",
   "author": "vulcan-lin"
 },
{
   "sha": "dba4425fde4088afbf7879e311ec43c6527dbab8",
   "author": "taizilongxu"
 }
]

如果能过滤一下, 选取 author 都是我的呢?

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[] | select(.author.login=="taizilongxu") | {author: .author.login, url: .url}'
{
  "author": "taizilongxu",
  "url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/3155c45d6b8eb3c2cb08bf62922b33f19333ff0e"
}
{
  "author": "taizilongxu",
  "url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/77bbc06a8fc0612816d26a534d8225fa888cb599"
}
{
  "author": "taizilongxu",
  "url": "https://api.github.com/repos/taizilongxu/douban.fm/commits/dba4425fde4088afbf7879e311ec43c6527dbab8"
}

假如我要在 author 里增加一个键值对 "phone": "110"

 $ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[0].commit.author.phone=110'
 [
   {
       "sha": "89682f6da75fcc896c00f1727f77ab325f3c1fab",
       "commit": {
             "author": {
                     "name": "xuxiao.xu",
                     "email": "xuxiao.xu@qunar.com",
                     "date": "2016-09-28T14:29:34Z",
                     "phone": 110
                   },
             "committer": {
                     "name": "xuxiao.xu",
                     "email": "xuxiao.xu@qunar.com",
                     "date": "2016-09-28T14:29:34Z"
                   },
             ...

 ]

如果要增加一条记录, 使用 length 确定 array 长度, 然后再加

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[length] += {"test": "test"}'
[
....
{
   "test": "test"
 }
]

使用 del() 删除每一个元组的 commit 值

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[] | del(.commit)'

直接赋值即可, 可以将每个元组的 sha 变为 1

$ curl -s 'https://api.github.com/repos/taizilongxu/douban.fm/commits?per_page=5' | jq '.[] | .sha=1'