一、jq 简介
JSON是一种轻量级的数据交换格式。其采用完全独立于语言的文本格式,具有方便人阅读和编写, 同时也易于机器的解析和生成。这些特性决定了JSON格式越来越广泛的应用于现代的各种系统中。 作为系统管理员,在日常的工作中无论是编辑配置文件或者通过http请求查询信息,我们都不可避免的要处理JSON格式的数据。 jq 是一款命令行下处理JSON数据的工具。其可以接受标准输入,命令管道或者文件中 的JSON数据,经过一系列的过滤器(filters)和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。 jq的这种特性使我们可以很容易地在Shell脚本中调用它。
二、常用基础命令
基础表达式(Basic filters)是 jq 提供的基本过滤器,用来访问 JSON 对象中的属性。基础表达式主要有以下几种:
- ‘.’ 符号:单独的一个’.’符号用来表示对作为表达式输入的整个 JSON 对象的引用。
- JSON 对象操作:jq 提供两种基本表达式用来访问 JSON 对象的属性:’.
’和’. ?’。正常情况下,这两个表达式的行为相同:都是访问对象属性,如果 JSON 对象不包含指定的属性则返回 null。区别在于,当输入不是 JSON 对象或数组时,第一个表达式会抛出异常。第二个表达式无任何输出。 - 数组操作:jq 提供三种基础表达式来操作数组:
- 迭代器操作(‘.[]’). 该表达式的输入可以是数组或者 JSON 对象。输出的是基于数组元素或者 JSON 对象属性值的 iterator。
- 访问特定元素的操作(‘.[index]’或’.[attributename]’)。用来访问数组元素或者 JSON 对象的属性值。输出是单个值
- 数组切片操作(‘.[startindex:endindex]’),其行为类似于 python 语言中数组切片操作。
- 表达式操作(‘,’和 ‘|’):表达式操作是用来关联多个基础表达式。其中逗号表示对同一个输入应用多个表达式。管道符表示将前一个表达式的输出用作后一个表达式的输入。当前一个表达式产生的结果是迭代器时,会将迭代器中的每一个值用作后一个表达式的输入从而形成新的表达式。例如’.[]|.+1’, 在这个表达式中,第一个子表达式’.[]’在输入数组上构建迭代器,第二个子表达式则在迭代器的每个元素上加 1。
内置运算,jq 内部支持的数据类型有:数字,字符串,数组和对象(object)。并且在这些数据类型的基础上, jq 提供了一些基本的操作符来实现一些基本的运算和数据操作。列举如下:
- 数学运算。对于数字类型,jq 实现了基本的加减乘除(/)和求余(%)运算。对于除法运算,jq 最多支持 16 位小数。
- 字符串操作。jq 提供字符串的连接操作(运算符为’+’),字符串的复制操作(例如:’a’*3 结果为’aaa’),以及字符串分割操作(将字符串按照指定的分割符分成数组,例如”sas”/“s”的结果为[“”,”a”,””],而”sas”/“a”的结果为[“s”,”s”]。
1、命令行帮助
1
~/tmp$ jq -h
2、jq直接读取文件
1
2
3
4
# xxx.JSON是我们要处理的JSON数据,我们可以直接将文件名传给jq
~/tmp$ jq -r '.' xxx.JSON
# 或者由其他程序读出文件内容,并传给jq
~/tmp$ cat xxx.JSON | jq -r '.'
需要说明的是 jq 只能接受 well form 的 JSON 字符串作为输入内容。也就是说输入内容必须严格遵循 JSON 格式的标准。所有的属性名必须是以双引号包括的字符串。对象的最后一个属性的末尾或者数组的最后一个元素的末尾不能有逗号。否则 jq 会抛出无法解析 JSON 的错误。
3、解析JSON,根据key获取value
1
2
3
4
5
6
7
8
9
10
11
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq '.publications'
# 单个值获取,解析不存在的元素,会返回null
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq '.publications[1].name'
# 嵌套解析,注意:json 数组的键命名必须为下划线"_",不能为"-",否则解析不了。解析不存在的元素,会返回null
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq 'keys'
# 内建函数-key,用来获取JSON中的key元素
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq 'has("publications")'
# 内建函数-has,用来是判断是否存在某个key
4、对已有JSON进行翻倍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
示例demo.json:
{
"code": 0,
"msg": "",
"store_name_list": [
{
"store_name": "gmail-demo-1"
}
]}
命令如下:
~/tmp$ demo=$(cat demo.json|jq '.store_name_list+=.store_name_list')
~/tmp$ echo "$demo"
结果如下:
{
"code": 0,
"msg": "",
"store_name_list": [
{
"store_name": "gmail-demo-1"
},
{
"store_name": "gmail-demo-1"
}
]}