昔我往矣

无比强大的shell之json解析工具jq

2016年01月27日

写脚本还是以shell为主,但是在调用api或者访问服务的时候,经常用到json,这时候会用python来解析json数据,所以是否需要解析json一直是我决定用python还是shell编写脚本的参考依据。某天遇到一个大神,他说你知道jq嘛,回去搜一搜,简直了。废话少说,上代码说话。

json工具

ubuntu用户可以直接apt-get安装,自己安装就好。

基础用法
下面是一个典型的json串:

$ aliyuncli slb DescribeLoadBalancers
{
    "LoadBalancers": {
        "LoadBalancer": [
            {
                "AddressType": "internet", 
                "RegionIdAlias": "cn-hangzhou", 
                "LoadBalancerId": "123", 
                "LoadBalancerName": "1.xnow.com"

            }, 
            {
                "AddressType": "internet", 
                "RegionIdAlias": "cn-hangzhou", 
                "LoadBalancerId": "456" ,
                "LoadBalancerName": "2.xnow.com"
        },
            {
                "AddressType": "internet", 
                "RegionIdAlias": "cn-hangzhou", 
                "LoadBalancerId": "789", 
                "LoadBalancerName": "3.xnow.com"  
            }
        ]
    },
    "RequestId": "xyz"
}

这串json实际上是我用aliyuncli管理工具获取到的三台阿里云slb的信息,当然是简化版,使用jq取得LoadBalancerName的方法如下:
获取某一台机器的LoadBalancerName:

$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer[1].LoadBalancerName"
"2.xnow.com"

获取所有LoadBalancerName

$ aliyuncli slb DescribeLoadBalancers | ".LoadBalancers.LoadBalancer[].LoadBalancerName"
"1.xnow.com"
"2.xnow.com"
"3.xnow.com"

利用jq的管道取出特定的字段,

$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer | .[0].LoadBalancerId"
"123"
#等于
$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer[0].LoadBalancerId"
"123"

拼接新json

自定义输出的字段名,拼接取得的字符串成新json:

$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer | \
{"id1" : .[0].LoadBalancerId, name1: .[0].LoadBalancerName}"
{
  "name1": "1.xnow.com",
  "id1": "123"
}

甚至:

$ aliyuncli slb DescribeLoadBalancers | jq "[.LoadBalancers.LoadBalancer[] | \
{"id" : .LoadBalancerId, name: .LoadBalancerName}]"
[
{
  "name": "1.xnow.com",
  "id": "123"
}
{
  "name": "2.xnow.com",
  "id": "456"
}
{
  "name": "3.xnow.com",
  "id": "789"
}
]

各种方法生成新json

$ aliyuncli slb DescribeLoadBalancers | jq "[.LoadBalancers.LoadBalancer[] | \
{"id" : .LoadBalancerId, name: .LoadBalancerName, type: [.AddressType]}]"
[
  {
    "type": [
      "internet"
    ],
    "name": "1.xnow.com",
    "id": "123"
  },
  {
    "type": [
      "internet"
    ],
    "name": "2.xnow.com",
    "id": "456"
  },
  {
    "type": [
      "internet"
    ],
    "name": "3.xnow.com",
    "id": "789"
  }
]

最后一例
看完上面的例子,相信就能够使用jq解析json了,下面再送上1个小命令,例如查看元素个数,如果shell使用for循环会用到:

$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers | length"
1
$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer | length"
3
$ aliyuncli slb DescribeLoadBalancers | jq ".LoadBalancers.LoadBalancer[0] | length"
4

更新:从json中获取多个字段
实例文档 example.json 内容如下:

[
  {
    "name": "libai",
    "age": "46"
  },
  {
    "name": "dufu",
    "age": "34"
  }
]

如果既要获取name,又要获取age, 可以采用如下的方式完成:

$ jq '.[] | .name + " is at age " + .age' example.json
"libai is at age 46"
"dufu is at age 34"

jq功能超级强大,甚至包括index,add,逻辑判断,正则表达式,debug,try-catch,while,split等等,可以作为一门语言来学,这里就不详细展开来,主要是我也不会。有兴趣看这里https://stedolan.github.io/jq/manual/

python和shell相比较而言,shell具有短平快的特点(其实,主要是python还不熟)。配合好用的工具,shell还是极其强大的。

当前暂无评论 »

添加新评论 »