优秀的编程知识分享平台

网站首页 > 技术文章 正文

命令行JSON解析神器jq(java 解析命令行参数)

nanyue 2024-10-23 12:01:22 技术文章 1 ℃

我们都知道现在JSON是最常用的配置和数据交换格式之一,尤其是大量的系统API接口现在基本上都是以JSON格式显示结果。JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON独立于语言的文本格式,具有典型的使C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等),JSON易于人阅读和编写。同时也易于机器解析和生成。

各种语言都有大量的JSON处理库,比如fastjson,Json-lib,jsoniter,jackson,gson等,我们可以很方便就可以写一个脚本获取接口的Json信息,并通过这些类库进行处理。

虽然如此,有些同学可能还是嫌写脚本太麻烦,有没有一种很简单就能上手就用,用完就扔的JSON工具呢?答案是肯定的。这就是本文虫虫要给大家介绍的一个命令行工具jq,注意jq不是曾经流行的JS库Jquery的缩写。

jq是一个出色的命令行JSON处理器,提供了用于查询,操作和使用JSON文件的大量功能。而且作为一个命令行工具,可配合UNIX管道使用,单行脚本处理JSON。

安装

jq是开源跨平台的软件,支持Linx,Mac OS和Windows,可通过应用包管理器、源码形式安装。

包管理安装

Debian和Ubuntu系:sudo apt-get install jq

redhat系:sudo yum install jq 或 sudo dnf install jq

openSUSE:sudo zypper install jq

Arch:sudo pacman -Sy jq

Mac OS:使用Homebrew安装,brew install jq

Windows:使用Chocolatey NuGet或者直接下载官方二进制包

chocolatey install jq

源码安装

git clone https://github.com/stedolan/jq.git

cd jq

autoreconf -i

./configure --disable-maintainer-mode

make

sudo make install

jq快速入门

为了方便以一个简单例子开始。首先我们调用GitHub的API,获取一个仓库的commit历史,并将其保存为example.json文件。

curl -o example.json 'https://api.github.com/repos/bollwarm/SecToolSet/commits'

要查看json内容最简单的是使用.表达式,会打印json的原始内容。

jq '.' example.json

json文件中的commit信息都是一个数组,其中一个commit可以使用.[x]操作,这和各个语言的数组操作也一样。比如:

第一个commit为.[0],以零开头。

jq '.[0]' example.json

| 操作符号是jq中的过滤器,过滤格式通过{...}来构建对象和属性,可以嵌套访问属性,例如.commit.message

下面语句获取第一个commit消息的commit.message和commit.committer.name并显示message和name:

jq '.[0] | {message: .commit.message, name: .commit.committer.name}' example.json

[]中如果为空表示获取所有的数组元素,获取所有commit消息和提交者:

jq '.[] | {message: .commit.message, name: .commit.committer.name}' example.json

jq中的数据表示为JSON流:每个jq表达式对JSON流中的各个值操作,其输出流可也包含任意数量的值。

通过仅用空格分隔JSON值即可对流进行序列化。这是cat显示友好的格式。如果想要将结果要输出作为数组形式的json格式,可以通过将过滤器用[]括住:

jq '[.[] | {message: .commit.message, name: .commit.committer.name}]' example.json

如果要获取一个commit的多个父提交的URL,由于该字段为多个元素以数组形式显示,如果直接使用.parents.html_url过滤则会下面的报错:

jq: error (at example.json:2268): Cannot index array with string "html_url"

对该类字段过滤时候,需要使用[.parents[].html_url]的数组解析格式:

jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]' example.json

管道

我们在入门部分介绍了jq的基本使用和显示。jq作为了一个标准的shell命令行工具,也是遵循UNIX POSIX原则的,比如管道。可以通过管道对接jq的数据输入和输出,这样可以jq实现和其他工具进行交互非常。下面的管道中,cat将文件通过管道传输到jq,然后通过管道传输到less管道。这对于查看大型JSON文件非常有用。

cat example.json | jq '.' | less

当然用管道对接less着色就失效了,这是一个副作用。

对键和值过滤

为了找到键和值,jq可以根据键进行过滤并返回值。入门部分我们已经讲了过滤键。我们再举一个简单例子,假设一个如下的JSON文档保存为dog.json。

jq可以通过在表达式中使用.键名来搜索值。

jq '.name' dog.json

CC

多个键搜索,中间用逗号分开:

jq '.breed,.name' dog.json

"金毛"

"CC"

可以将键名自定义:

jq '{"主人":.owner,"爱好":.likes}' dog.json

数组遍历和查询

入门部分我们说过,要搜索数组中的项目,请使用括号语法,索引从0开始。

jq '.likes[1]' dog.json

"球球"

数组的多个元素也可能返回。

echo '["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",",","!"]'|jq '[.[12],.[4],.[17],.[17],.[24],.[26],.[2],.[7],.[17],.[8],.[18],.[19],.[12],.[0],.[18],.[27]]

结果:" MERRY,CHRISTMAS!" 祝大家圣诞快乐!

数据转换

jq不仅可以用于从JSON对象获取值显示,而且还可以用于JSON转换为新的数据结构。比如:对dog.json 可以创建一个包含狗名和爱好的键,组成一个新数组。

jq '[.name,.likes[]]' dog.json

[

"CC",

"骨头",

"球球",

"狗粮"

]

需要把JSON数据从一种结构转移到另一种数据结构的数据转换时,非常有用。

jq还可以对JSON对象中的数据进行操作。

echo '{"a": 1 , "b": 2}'|jq '.a+100'

101

其实上,+对字符串也是适用的,比如前面的圣诞快乐单行也可以为:

echo '["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",",","!"]'|jq '[.[12]+.[4]+.[17]+.[17]+.[24]+.[26]+.[2]+.[7]+.[17]+.[8]+.[18]+.[19]+.[12]+.[0]+.[18]+.[27]]'

结果:

[

"MERRY,CHRISTMAS!"

]

删除JSON键

jq也支持从JSON对象中删除键。删除后输出就不包含删除key的JSON对象。删除键使用del()函数,还是以dog.json为例:

jq 'del(.owner)' dog.json

结果中就不包括owner键了:

{

"name": "CC",

"breed": "金毛",

"age": "4",

"likes": [

"骨头",

"球球",

"狗粮"

]

}

jq 'del(.)' dog.json

null

所有键都被删了,所以上面结果为null。

值映射

jq可以映射值并在每个值上执行操作。在下面的示例中,数组中的每个键进行映射并做数值计算加2。

echo '[1,2,3,4,5,6]' |jq 'map(.+2)'

[

3,

4,

5,

6,

7,

8

]

总结

本文介绍了一个命令行下的json解析神器,更多文档可以参考官方网站,可以托管仓库的wiki页。

最近发表
标签列表