jq使一个开源的处理json文件的命令行工具,这篇博客会介绍如何使用jq对json文件进行格式化输出,筛选数据,以及使用函数来统计分析,或者改变json数据。

简介

JSON (Javascript Object Notation) 数据格式是广泛用于web应用和服务器之间进行交换数据的格式。JSON格式灵活直观,易于阅读,它使用{}包裹:分隔的数据来表示键值对,使用[]来表示列表,支持number,string,boolean不同的数据类型。不过 linux 中常用数据处理命令,比如grepsed并不是十分适合处理JSON格式的数据。jq是一个针对命令行中处理JSON不便而开发的工具,它使用C语言编写,可以在不同系统运行,不需要运行依赖项,可以通过pipe与其它指令配合。

这篇博客的下面内容会介绍如何使用jq来格式化JSON数据,如何筛选数据内容,如何使用其中的函数来操作和分析JSON数据。

安装jq

在debian系统可以使用包管理器安装:

sudo apt install jq

windows系统可以使用:

choco install jq

可以选择到到下载页面手动安装jq。

对JSON数据格式化

对JSON数据格式化的意思是让数据打印的时候显示合适的缩进,括号对齐。jq命令可以通过'.'指令将数据内容按照标准格式排版,.符号的意思是identity命令。你可以使用文件名作为参数来使用jq命令,或者使用pipe将内容从stdin输入到jq命令。

# pipe data into jq
echo '{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"} ] } } }' | jq '.'

# use curl to get data from website then pipe
curl 'https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia/all-access/all-agents/Talking_Heads_discography/daily/20210928/20210930' | jq '.'

# use filename as argument
jq '.' menu.json

筛选数据内容

从键值对中筛选

jq中根据键来寻找值可以使用.field操作符,使用.后面加上键的名称。

# filter with key
jq '.menu' menu.json

# filter nested key-value data
jq '.menu.id' menu.json

# filter multiple items
jq '.menu.id, .menu.value' menu.json

从列表中筛选

从列表中筛选可以使用[]符号,如果在[]中没有输入任何内容,那么jq会列举每个列表中的元;如果[]中输入了序号,那么jq就会筛选出指定序号的内容。

echo '[ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"} ]' | jq '.[]'

jq '.[1]' submenu.json

jq '.[0:2]' submenu.json

# 得到列表中每个元素的value部分
jq '.[].value' submenu.json

# 和上一行同样的效果
jq '.[] | .value' submenu.json

jq '.menu.popup.menuitem | .[1]' menu.json

使用内建函数

jq中包含很多函数可以直接应用在json数据上对其进行分析或者操作。

分析JSON数据

# 使用length函数计算array的长度
jq '.menu.popup.menuitem | length' menu.json

# 使用max函数寻找数组中的最大值,最外层的[]让输出结果为另一个数组
jq '[.[].priority] | max' submenu.json

# 使用keys函数来查看所有的key
jq '.menu | keys' menu.json

# has函数可以用来判断一个元素是否有给定的键,map将函数作用到数组中的每一个元素
jq 'map(has("priority"))' submenu.json

# unique可以移除重复项
jq 'map(.onclick) | unique' submenu.json

操作JSON数据

# select可以根据条件筛选数据
jq '.[] | select(.priority>18)' submenu.json

# 多个条件直接可以使用
jq '.[] | select(.value=="Close" or .value=="Open")' submenu.json

# select可以和test函数一起使用,通过正则表达式来寻找能够匹配模板的元素。这里匹配所有onclick值开头为O字符的元素
jq '.[] | select(.onclick|test("^O."))' submenu.json

# 使用del删除所有元素的priority值
jq '.[] | del(.priority)' submenu.json

# 所有元素priority值加2
jq  '.[] | .priority+ 2' submenu.json

# 同样的效果
jq  'map(.priority+ 2)' submenu.json

结语

jq是一个方便在命令行中操作json数据的开源工具,它能够在不同的平台安装运行,可以通过包管理器直接安装。jq可以用简短的命令来格式化JSON数据,筛选数据,操作数据,可以同pipe和其它unix命令相结合。

参考