使用jq在命令行处理json文件
jq使一个开源的处理json文件的命令行工具,这篇博客会介绍如何使用jq对json文件进行格式化输出,筛选数据,以及使用函数来统计分析,或者改变json数据。
简介
JSON (Javascript Object Notation) 数据格式是广泛用于web应用和服务器之间进行交换数据的格式。JSON格式灵活直观,易于阅读,它使用{}
包裹:
分隔的数据来表示键值对,使用[]
来表示列表,支持number,string,boolean不同的数据类型。不过 linux 中常用数据处理命令,比如grep
和sed
并不是十分适合处理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命令相结合。