linux下的json解析工具jq的使用笔记

如何使用强大的命令行json解析工具jq

一、json的基础知识

1.json是什么

定义:json是一种通用的数据交换格式,其本质是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,json被广泛应用于数据交换中。(如前后端数据交换)
形式:数组,对象
通过这两种结构可以表示各种复杂的结构

1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种

2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 [“java”,“javascript”,“vb”,“c++”…],取值方式和所有语言中一样,使用索引获取(从0开始),字段值的类型可以是数字、字符串、数组、对象几种。

例如:我们往一个url发送GET请求,返回多个json对象,这些json对象组合成一个json对象数组。
json对象(格式化形式)

{
    "id":1,
    "name":"zhangsan",
    "age":24,
    "desc":"无名侠客",
    "company":[
        "baidu",
        "google",
        "alibaba"
    ]
}

json对象数组(格式化形式)

[
    {
        "id":1,
        "name":"zhangsan",
        "age":24,
        "desc":"无名侠客",
        "company":[
            "baidu",
            "google",
            "alibaba"
        ]
    },
    {
        "id":2,
        "name":"lisi",
        "age":18,
        "desc":"勇往直前",
        "company":[
            "tencent",
            "google",
            "bytedance"
        ]
    }
]

压缩的形式:(实际传输的时候是压缩形式)

{"id":1,"name":"zhangsan","age":24,"desc":"无名侠客","company":["baidu","google","alibaba"]}

总结:

json对象是以{}包括起来的无序的键值对集合,数组是有序的值集合。(这里的值可以是数字,字符串,json对象,数组)

2.json序列化和反序列化

序列化:字典 / 列表 / 数字 /对象 -经过序列化 —>字符串 (从面向对象的角度来说,序列化就是把对象转换成json格式的字符串

反序列化:字符串 —> 字典 / 列表 / 数字 /对象 (反序列化就是把json字符串变回对象) 为什么要序列化

  • 要把内容写入文件
  • 网络传输数据 序列化

参考文档:json语法

二、如何在命令行使用jq工具

背景:一般情况下我们可以有很多办法处理返回回来的json数据,使其以我们想要格式显示,在集成开发环境中可以用各种类库来实现,而在linux中可以通过awk语法对json数据进行处理,更为便捷的办法就是采用jq工具。

1.如何下载jq工具

ubuntu系统下:

apt install jq

linux系统下

yum install jq

下载失败的几种原因:

  • 没有在root用户权限下下载
  • 没有配置镜像源

2.jq表达式

①什么是jq表达式
  • jq表达式实际上就是过滤器,过滤出我们想要的数据格式。
  • jq 表达式支持串行化操作。一个复杂的表达式可以有多个简单的,以"|"符号分割的,串行化执行的表达式组成。每个表达式以其前边表达式的结果为输入。例如:有 JSON 数据{“name”:{“firstname”:“Tom”,“lastname”:“Clancy”}}。我们要查询 lastname 属性可以使用表达式’.name|.lastname’。
②基础表达式

基础表达式(Basic filters)是 jq 提供的基本过滤器,用来访问 JSON 对象中的属性。基础表达式也是实现更复杂查询功能的基础。基础表达式主要有以下几种:

  • ‘.’ 符号。整个JSON对象作为表达式输入
  • 数组操作,具体见后文
  • 表达式操作(‘,‘和 ‘|’)。表达式操作是用来关联多个基础表达式。其中逗号表示对同一个输入应用多个表达式。管道符表示将前一个表达式的输出用作后一个表达式的输入。当前一个表达式产生的结果是迭代器时,会将迭代器中的每一个值用作后一个表达式的输入从而形成新的表达式。例如’.[]|.+1’, 在这个表达式中, 第一个子表达式'.[]'在输入数组上构建迭代器,第二个子表达式则在迭代器的每个元素上加 1。

3.使用jq工具

参考文档:jq Manual

①查看jq的帮助指令

在命令行输入jq --help

jq --help
jq - commandline JSON processor [version 1.6]

Usage:  jq [options] <jq filter> [file...]
        jq [options] --args <jq filter> [strings...]
        jq [options] --jsonargs <jq filter> [JSON_TEXTS...]

jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.

The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).

For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq

Example:

        $ echo '{"foo": 0}' | jq .
        {
                "foo": 0
        }

Some of the options include:
  -c               compact instead of pretty-printed output;
  -n               use `null` as the single input value;
  -e               set the exit status code based on the output;
  -s               read (slurp) all inputs into an array; apply filter to it;
  -r               output raw strings, not JSON texts;
  -R               read raw strings, not JSON texts;
  -C               colorize JSON;
  -M               monochrome (don't colorize JSON);
  -S               sort keys of objects on output;
  --tab            use tabs for indentation;
  --arg a v        set variable $a to value <v>;
  --argjson a v    set variable $a to JSON value <v>;
  --slurpfile a f  set variable $a to an array of JSON texts read from <f>;
  --rawfile a f    set variable $a to a string consisting of the contents of <f>;
  --args           remaining arguments are string arguments, not files;
  --jsonargs       remaining arguments are JSON arguments, not files;
  --               terminates argument processing;

Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].

See the manpage for more options.
②常用参数说明

-s 表示将输入的多个json对象组合成一个json数组,也就可以通过索引来操作该JSON数组了。具体效果如下:

$ cat test.json 现在输出的是多个json对象
{
        "id":1,
        "name":"zhangsan",
        "age":24,
        "desc":"无名侠客",
        "company":[
                "baidu",
                "google",
                "alibaba"
        ]
}
{
        "id":2,
        "name":"lisi",
        "age":18,
        "desc":"勇往直前",
        "company":[
                "tencent",
                "google",
                "bytedance"
        ]
}
$ jq  '.[1]'<test.json  #无法直接用索引的方式获取对象
jq: error (at <stdin>:11): Cannot index object with number
jq: error (at <stdin>:22): Cannot index object with number

$ jq -s '.[1]'<test.json  ##加了-s参数,转换成数组对象,就可以直接用索引的方式获取对象
{
  "id": 2,
  "name": "lisi",
  "age": 18,
  "desc": "勇往直前",
  "company": [
    "tencent",
    "google",
    "bytedance"
  ]
}

-r直接输出原字符串,而不是JSON文本,也就是把引号去掉。具体如下:

➜ ~ jq '.[].name' <test.json
"zhangsan"
"lisi"
➜ ~ jq -r  '.[].name' <test.json
zhangsan
lisi

-S给JSON对象的内容按键排序

jq -S .<test.json
[
  {
    "age": 24,
    "company": [
      "baidu",
      "google",
      "alibaba"
    ],
    "desc": "无名侠客",
    "id": 1,
    "name": "zhangsan"
  },
  {
    "age": 18,
    "company": [
      "tencent",
      "google",
      "bytedance"
    ],
    "desc": "勇往直前",
    "id": 2,
    "name": "lisi"
  }
]

4.案例分析

①格式化显示json字符串

用单引号把json数据包括起来就是json字符串,如:'json数据'
说明:利用管道符的传递功能,用jq处理输出输入数据,使其按规定格式显示。

格式化显示全部字符串:
jq .

$ echo '{"id":1,"name":"zhangsan","age":24,"desc":"无名侠客","company":["baidu","google","alibaba"]}' | jq .
{
  "id": 1,
  "name": "zhangsan",
  "age": 24,
  "desc": "无名侠客",
  "company": [
    "baidu",
    "google",
    "alibaba"
  ]
}

②如何调用jq工具

背景:test.json是我们存储json数据的文件。

$ jq . test.json   #等价于jq . <test.json
[
  {
    "id": 1,
    "name": "zhangsan",
    "age": 24,
    "desc": "无名侠客",
    "company": [
      "baidu",
      "google",
      "alibaba"
    ]
  },
  {
    "id": 2,
    "name": "lisi",
    "age": 18,
    "desc": "勇往直前",
    "company": [
      "tencent",
      "google",
      "bytedance"
    ]
  }
]

③数组操作。

jq 提供三种基础表达式来操作数组:

  • 迭代器操作(‘.[]’). 该表达式的输入可以是数组或者 JSON 对象。输出的是基于数组元素或者 JSON 对象属性值的 iterator。
  • 访问特定元素的操作(‘.[index]‘或’.[attributename]’)。用来访问数组元素或者 JSON 对象的属性值。输出是单个值
  • 数组切片操作(‘.[startindex:endindex]’),其行为类似于 python 语言中数组切片操作。
#访问特定属性的值
$ jq '.[0]."desc"'<test.json
"无名侠客"
$ jq '.[0].desc'<test.json
"无名侠客"

$ jq '.[0]'<test.json #索引操作
{
  "id": 1,
  "name": "zhangsan",
  "age": 24,
  "desc": "无名侠客",
  "company": [
    "baidu",
    "google",
    "alibaba"
  ]
}
$ jq '.[].name'<test.json #遍历输出所有的姓名(迭代器)
"zhangsan"
"lisi"
$ jq '.[0].company[0:2]'<test.json #切片操作
[
  "baidu",
  "google"
]



④使用jq串行解析和显示json中的多个字段

test.json文件

[
  {
    "id": 1,
    "name": "zhangsan",
    "age": 24,
    "desc": "无名侠客",
    "company": [
      "baidu",
      "google",
      "alibaba"
    ]
  },
  {
    "id": 2,
    "name": "lisi",
    "age": 18,
    "desc": "勇往直前",
    "company": [
      "tencent",
      "google",
      "bytedance"
    ]
  }
]

现在有test.json文件,我们需要使用jq,连续显示名字和年龄,效果如下

zhangsan 24
lisi     18

操作:

$ jq  '.[] | "\(.name) \(.age)"' <test.json
"zhangsan 24"
"lisi 18"

如何把双引号去掉呢,加上-r参数

$ jq  -r '.[] | "\(.name) \(.age)"' <test.json
zhangsan 24
lisi 18

⑤并行显示多个字段,用,同时使用多个表达式

样本数据

➜ ~ jq  .<test.json
[
  {
    "id": 1,
    "name": "zhangsan",
    "age": 24,
    "desc": "无名侠客",
    "company": [
      "baidu",
      "google",
      "alibaba"
    ]
  },
  {
    "id": 2,
    "name": "lisi",
    "age": 18,
    "desc": "勇往直前",
    "company": [
      "tencent",
      "google",
      "bytedance"
    ]
  }
]

,多个表达式组合的不同效果

➜ ~ jq '.[0].desc,.[0].name'<test.json
"无名侠客"
"zhangsan"
➜ ~ jq '.[0].desc,.[1].name'<test.json
"无名侠客"
"lisi"
➜ ~ jq '.[].desc,.[].name'<test.json
"无名侠客"
"勇往直前"
"zhangsan"
"lisi"
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西里小诸葛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值