jq是一个shell下的json解析工具,功能强大。
不加任何选项和表达式的作用是格式化json字符串,比较实用
1
2
3
| $ echo '{"key":"va", "key2":"val2"}'|jq #格式化echo里面的json
$ cat t.txt|jq #格式化t.txt里面的json
$ jq . t.txt #jq打开文件,并格式化t.txt里面的json
|
根据key查询json可以写成.key,如果key是特殊的字符,比如全数字需要用引号括起来: ."key"
.foo.bar的形式类似于shell的管道符|,.foo.bar等于.foo|.bar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #如果key对应的val存在则输出val
$ echo '{"foo": 42, "bar": "less interesting data"}' | jq '.foo'
> 42
#如果key对应的val值不存在则输出null
$ echo '{"notfoo": true, "alsonotfoo": false}' | jq '.foo'
> null
$ echo '{"111":"222", "333":"444"}'| jq '.["111"]'
> "222"
#效果和上面一条一样
$ echo '{"111":"222", "333":"444"}' | jq '."111"'
> "222"
## 根据key, 更新value
$ echo '{"111":"222", "333":"444"}' | jq '."111" = "aaa" '
> '{"111":"aaa", "333":"444"}'
## 根据key, 更新value, 使用变量
$ echo '{"111":"222", "333":"444"}' | jq -- '."111" = "aaa" '
> '{"111":"aaa", "333":"444"}'
|
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
26
27
| #查询数组第1个元素
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[0]'
#输出
{ "name": "JSON", "good": true }
#查询第3个元素,需要注意的是数组的下标是从0开始算的
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' |jq '.[2]'
#输出
null
#查询下标为2到3之间的元素
$ echo '["a","b","c","d","e"]'|jq '.[2:4]'
#输出
[ "c", "d" ]
#查询下标为3之前的元素
$ echo '["a","b","c","d","e"]'|jq '.[:3]'
#输出
[ "a", "b", "c" ]
#查询倒数第1-2个元素
$ echo '["a","b","c","d","e"]'|jq '.[-2:]'
> [ "d", "e" ]
#查询倒数第2个元素
$ echo '["a","b","c","d","e"]' jq '.[-2]'
> "d"
|
可以使用.[]语法,查询json对象的所有值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #拿到key的val以及key2的val2
$ echo '{"key":"val", "key2":"val2"}' | jq '.[]'
> "val"
> "val2"
#拿到key的val(一个object),key2的val
$ echo '{"key":{"key3":"val3", "key4":"val4"}, "key2":"val2"}' | jq '.[]'
#输出
> { "key3": "val3", "key4": "val4" }
> "val2"
#拿到json数组里面的值
$ echo ' [{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[]'
> { "name": "JSON", "good": true } { "name": "XML", "good": false }
|
如果要写多个过滤条件使用,号,现输出,左边的结果在输出,右边的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| $ echo '{"foo": 42, "bar": "something else", "baz": true}' | jq '.foo,.bar,.baz'
#输出
42
"something else"
true
#.key和[]表达式可以组合使用
$ echo '{"user":"stedolan", "projects": ["jq", "wikiflow"]}'|jq '.user,.projects[]'
#输出
"stedolan"
"jq"
"wikiflow"
#可以使用,一次查询数组里的多个元素
$ echo '["a","b","c","d","e"]'|jq '.[4,3]'
#输出
"e"
"d"
|
shell里面的|是连接各个shell命令的通道,像大管道套小管道,过滤器就是命令,可以很方便的过滤出想要的数据来
jq里面也有|符号
1
2
3
4
5
6
7
8
9
10
11
| #可以先用.[]拿到值,再使用|(管道)拿到name
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]'|jq '.[] | .name'
#输出
"JSON"
"XML"
######把查询结果包装成一个数组(array)--使用[]符号
[]在jq里面表示数组,可以现查询再使用[]把查询结果包装成数组
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]'|jq '[.[]|.name]'
#输出
[ "JSON", "XML" ]
|
把查询结果包装成一个对象(object)
1
2
3
4
5
6
7
8
9
10
11
12
| #修改json的key名
$ echo '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}'| jq '{user1: .user, title2: .titles}'
> { "user1": "stedolan", "title2": [ "JQ Primer", "More JQ" ]}
#如果其中一个表达式产生多个结果,那最终生成的json也有多个结果
#其中.titles[]会查询出两个结果,那最终生成的json也是两个
$ echo '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}'|jq '{user, titles:.titles[]}'
> { "user": "stedolan", "titles": "JQ Primer" }{ "user": "stedolan", "titles": "More JQ"}
#如果想使用原来的json某个key的值作新的json的key,可以使用(.key)语法
$ echo '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}'| jq '{(.user): .titles}'
> { "stedolan": ["JQ Primer", "More JQ" ]}
|
+运算符需要两个相同输入,并把结果加在一起
- 数字常规的加法
- array拼接成一个大的数组
- string拼接成一个大的string
- object也是合并操作,如果有两个key相同的object新的覆盖旧的
null可以与任何值相加,返回另外一个值
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
26
27
28
| #数字相加
$ echo '{"a":1}'| jq '.a + 1'
#输出
2
#array相加
$ echo '{"a": [1,2], "b": [3,4]}' | jq '.a+.b'
#输出
[ 1, 2, 3, 4]
#string相加
$ echo '{"a": "hello", "b": "world"}'|jq '.a+.b'
#输出
"helloworld"
#object相加
$ echo null | jq '{a: 42} + {b: 2} + {c: 3} + {a: 1}'
#输出
{ "a": 1, "b": 2, "c": 3}
#有空值相加的情况
$ echo '{"a": 1}'|jq 'null +.a'
#输出
1
$ echo '{}'|jq '.a+1'
#输出
1
|
-号运算符用于数字,用于数组,会在第一个数组删除第二个数组中出现的所有项
1
2
3
4
5
6
7
8
9
10
| #数字相减
$ echo '{"a":4}'|jq '4 - .a'
#输出
0
#数组相减
$ echo ' ["xml", "yaml", "json"]' |jq '. - ["xml", "json"]'
#输出
[ "yaml"
]
|
/只能用在数字类型上
1
2
3
| $ echo 5|jq '10 / . * 3'
#输出
6
|
length用于不同类型值的长度
- string:返回字符串中字符的个数,如果有中文返回中文的个数
- array: 返回数组元素的个数
- object: 返回键-值对的个数
1
2
3
| echo '["郭", [1,2], "string", {"a":2}, null]'| jq '.[]|length'
#输出
12610
|
keys可以返回json键名数组,其中keys与keys_unsorted区别是keys返回的数组是排过序的
keys_unsorted返回的数组是不排序
当json的顶层元素是数组时,keys返回数组的下标
1
2
3
4
5
6
7
8
9
10
11
| $ echo '{"abc": 1, "abcd": 2, "Foo": 3}'|jq 'keys'
#输出
[ "Foo", "abc", "abcd" ]
$ echo '{"abc": 1, "abcd": 2, "Foo": 3}'|jq 'keys_unsorted'
#输出
[ "abc", "abcd", "Foo" ]
$ echo '["aaa", "bbb", "ccc"]'|jq 'keys'
#输出
[ 0, 1, 2]
|
返回输入的json对象是否有给定的key,或者数组存在指定的索引,有返回true,没有返回false
1
2
3
4
5
6
7
| $ echo '[{"foo":123, "abc":456}, {"cde":789, "fgh":111}]' | jq 'map(has("foo"))'
#输出
[ true, false ]
$ echo '[[0,1], ["a","b","c"]]'|jq 'map(has(2))'
#输出
[ false, true ]
|
检查输入的键是否在对象中,或者输入的索引存在数组中,有返回true,没有返回false,本质上是反过来的has
1
2
3
4
5
6
7
8
9
| $ echo '["foo", "123"]'| jq '.[]|in({"foo":123})'
#输出
true
false
$ echo '[2, 3]'| jq '.[]|in(["a", "b", "c"])'
#输出
true
false
|
del用来删除json 对象的键和值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #删除一个键值对
echo '{"aaa": 111, "bbb": 222, "ccc":33}'|jq 'del(.aaa)'
#输出
{ "bbb": 222, "ccc": 33}
#删除多个键值对
echo '{"aaa": 111, "bbb": 222, "ccc":33}'|jq 'del(.["aaa", "bbb"])'
#输出
{ "ccc": 33}
#根据下标删除数组元素
echo '[111, 222, 33]'|jq 'del(.[1,2])'
#输出
[ 111]
|
- to_entries 把json对象转成键-值对数值
- from_entries 键-值对数组转成json对象
- with_entries 是 to_entries | map(foo) | from_entries 的缩写
1
2
3
4
5
6
7
8
9
10
11
12
13
| $ echo '{"aa":11, "bb":22}'|jq 'to_entries'
#输出
[ { "key": "aa", "value": 11 }, { "key": "bb", "value": 22 }]
$ echo '[{"key" : "aa", "value": "11"}, {"key":"bb", "value": "22"}]'|jq 'from_entries'
#输出
{ "aa": "11", "bb": "22"
}
#修改key名
$ echo '{"a": 1, "b": 2}'|jq 'with_entries(.key |= "student_" + .)'
#输出
{ "student_a": 1, "student_b": 2}
|
select 是过滤器,里面可以写表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #选择数组里面的偶数
$ echo [1,2,3,4,5,6]|jq 'map(select(.%2 == 0))'
#输出
[
2,
4,
6
]
$ echo '[{"id": "first", "val": 1}, {"id": "second", "val": 2}]'| jq '.[]|select(.id=="first")'
#输出
{
"id": "first",
"val": 1
}
|
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
| {
"ID": 0,
"Name": "ltptest",
"Owner": "ltptest",
"DpReplicaNum": 3,
"MpReplicaNum": 3,
"Status": 0,
"Capacity": 30,
"RwDpCnt": 25,
"MpCnt": 1,
"DpCnt": 25,
"AvailSpaceAllocated": 3000,
"Tokens": {
"bHRwdGVzdCMxIzE1NzY4MjU1MzY=": {
"TokenType": 1,
"Value": "bHRwdGVzdCMxIzE1NzY4MjU1MzY=",
"VolName": "ltptest"
},
"bHRwdGVzdCMyIzE1NzY4MjU1MzY=": {
"TokenType": 2,
"Value": "bHRwdGVzdCMyIzE1NzY4MjU1MzY=",
"VolName": "ltptest"
}
}
}
|
1
2
| $ jq '.Tokens | .[] | select( .TokenType == 2) | .Value'
"bHRwdGVzdCMyIzE1NzY4MjU1MzY="
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| # 获取 docker image下载量
$ curl "https://hub.docker.com/v2/repositories/chubaofs/" 2>/dev/null | \>
jq 'reduce (.results | .[] | .pull_count ) as $item (0; .+$item) '
# strftime
$ echo '[ { "CreateTime": 1629968504 }, { "CreateTime": 130675857 } ]' | \
jq '.[].CreateTime |= strftime("%Y-%m-%d_%H:%M:%S")'
# 计算百分比及格式化dataSize
echo '[ { "UseSize": 1629968504, "TotalSize": 10222023 }, { "UsedSize": 130675857, "TotalSize": 2132 } ]' | \
jq '[
.[] | . + { Ratio: (.UsedSize/.TotalSize | .*100 | floor | ./100 ) } |
(
["B", "KB", "MB", "GB", "TB", "PB", "ZB"] as $unit |
.TotalSize |= ( . as $size |
($size | [until(.<1024; ./1024)] | .[0] | .*100 | floor | ./100 | tostring) +
"_" +
($size | log10 | ./3 | floor as $l | $unit[$l] )
)
)
] '
>
[
{
"UsedSize": 1629968504,
"TotalSize": "9.74MB",
"Ratio": 0
},
{
"UsedSize": 130675857,
"TotalSize": "2.08KB",
"Ratio": 0
}
]
## 更新对象属性数组中的某一属性值
$ echo '{"Replicas":[ { "ReportTime": 1629968504 }, { "ReportTime": 130675857 } ]}' | \
jq -r '.Replicas[] |= (.ReportTime |= strftime("%Y-%m-%dT%H:%M:%S"))'
>
{
"Replicas": [
{
"ReportTime": "2021-08-26T09:01:44"
},
{
"ReportTime": "1974-02-21T10:50:57"
}
]
}
|
- https://gist.github.com/olih/f7437fb6962fb3ee9fe95bda8d2c8fa4
- jq