初探linux json处理器jq

2,098 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

什么是jq

jq简介

其官网为:stedolan.github.io/jq/

官网解释的是:“jq是一个轻量级且灵活的命令行JSON处理工具”。

由上,我们可以得出如下信息

  • 轻量且灵活
  • 命令行json处理工具

jq主要是由c语言编写,目前(2022年6月22日)最新版本为1.6(这个版本还是在2018年11月发布的),其github地址为:github.com/stedolan/jq,我们可以像sed那样,使用jq来处理json数据,包括:切片、过滤等。

我们为什么要用jq

我们或多或少,在编写shell的过程中,有需要解析json的需求,通常我们的做法是调用我们编写的高级程序,例如python来处理该json数据,然后再返回shell,若我们学习了jq后,我们无需外部调用即可处理json数据。

安装jq

debian系列

直接使用apt安装即可

apt-get install jq

redhat系列

直接使用yum安装即可

yum install jq

版本查看

使用jq --version可以查看版本

开始使用jq

通过例子的方式来逐步讲解jq的使用

假设你已经会基本的json

将数据转换为json格式输出

我们使用jq '.'可以实现格式化输出

例如

我们需要格式化{"id":0,"name":"pdudo","site":"juejin"}

使用命令:echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq .

获取json中某个key的值

可以使用jq '.keyName'来获取keyName的值

我们还是使用如上数据: {"id":0,"name":"pdudo","site":"juejin"},我们将获取name的值

命令: echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq '.name'

若想获取多个数据,可以使用,间隔,例如,我们不仅想获取name还想获取site的值

命令: echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq '.name,.site'

json中的key输出出来并且放到数组中

我们可以使用jq 'keys'json中的key输出出来且放入数据中

例如

我们还是使用如上json数据

使用命令:echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq 'keys'

获取json数组的长度

可以使用jq '.|length'来获取数组长度

|: 在jq中表示将上一个jq过滤器的输出作为下一个过滤器的输入,和shell管道类似

所以,我们想获取数组长度

例如,上一个案例,我们已经将jsonkey放入数组了,我们获取一下长度

命令: echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq 'keys' | jq '.|length'

如上我们知晓jq中的|也会将上一个过滤器输出作为下一个过滤器输入,所以,我们可以直接在js 'keys'后加入|length

我们可以这么写:echo '{"id":0,"name":"pdudo","site":"juejin"}' | jq 'keys|length',也可以获取数据

获取数组指定数据

可以使用jq '.[0]'来获取下标为0json数据,下标以此类推

例如有如下数据:["id","name","site"]

我们来获取下标为01的数据

命令: echo '["id","name","site"]' | jq '.[0]'

使用jq '.[]'是获取json的数组的所有数据

命令: echo '["id","name","site"]' | jq '.[]'

为每个数组运行过滤器

我们可以使用map

一般我们很少单独使用map,都会和select配合使用,所以请直接看下一个案例即可

使用jq赛选数据

我们可以使用jq select()赛选数据

例如,我们构建了如下数据

我们想赛选一下该json数据的info数组中sex2的数据

这里先直接给出命令,后面再做逐步解析

命令: echo '{"info": [{"name": "bob","age": 32,"sex": 1},{"name": "tom","age": 58,"sex": 2},{"name": "tom","age": 58,"sex": 2}]}' | jq '.info|map(select(.sex== 2))'

命令解析: 要想获取sex2的数据,那么,首先我们的获取info的信息,如前面所述,我们可以使用jq .info获取info数组的信息

我们得到数据后,现在要进行计算,map进行包裹,然后使用select赛选数据,map将为输入数组的每个元素运行过滤器,select将对输入进行匹配,若结果为true则输出,否则不进行输出,所以我们组合下来则为map(select(.sex== 2))

结合上一个取info我们使用过滤管道,即可得到命令: jq '.info|map(select(.sex== 2))'

不仅如此,我们还可以利用该数据做数据比较

例如:我们想查询age大于50的数据

命令: jq '.info|map(select(.age > 50))'

实际演示

我准备了一个实际案例,来讲解jq使用

查询符合条件的email

假设有如下json数据,获取age大于等于30email地址

我们将上述文件放置在text1.txt文件中

我们可以这样来编写

命令: cat text1.txt | jq '. | map(select(.age>=30)) | .[] | .email'

查询符合条件的部分信息

如上面例子,我们想通过age大于等于30,且返回nametel组成新的json

我们可以这样写

命令: cat text1.txt| jq '.|map(select(.age>=30))|.[]|{"name": .name,"tel": .tel}'

总结

对于jq而言,它是有学习成本的,若不介意在shell中嵌套python或者其他高级语言来处理json,也是可以的,但是单在shell或者命令行环境下,jq是处理json数据的不二之选,为了炫酷效果大可不必,解决问题才为第一要务。