Shell下处理JSON数据工具向导

目录

shell 复制代码
	jq程序是一个"过滤器"。它接受一个输入, 然后生成一个输出,有很多内置的过滤器用于提取对象的特定字段,或者将数字转换为字符串, 或其他各种标准任务。
	该过滤器可以以各种方式组合,可以通过管道将将一个滤波器转换为另一个滤波器,或收集滤波器的输出为一个数组。
	有些过滤器会产生多个结果,例如, 生成其输入数组的所有元素。管道过滤器 第二次运行第二过滤器,用于每个元素, 阵一般来说,用循环和迭代完成的事情 在其他语言中,只是通过将jq中的过滤器粘合在一起来完成。
# 重要的是要记住,每个过滤器都有一个输入和一个输出。即使是像"hello" 或 42 这样的文字也是过滤器-它们采用输入, 但总是产生与输出相同的文字。的操作 联合收割机两个过滤器,如加法,通常提供相同的输入, 两者和联合收割机组合结果。所以,你可以实现一个平均 过滤器作为add / length -将输入数组都馈送到add 滤波器和length滤波器,然后进行除法。

	jq过滤器在JSON数据流上运行。jq的输入是解析为空格分隔的JSON值序列, 一次一个地通过所提供的过滤器。过滤器的输出被写入标准输出,作为以换行符分隔的JSON数据序列。
	最简单和最常见的过滤器(或jq程序)是`.`, 它是恒等运算符,复制jq的输入,处理器到输出流。 因为 jq 处理器从输入流读取JSON文本, 然后漂亮的打印输出,`.` 程序的主要用途是验证并打印输入。 JQ编程语言是相当丰富的,它允许的不仅仅是验证和精美印刷。
	# 注意:注意shell的引用规则是很重要的。 作为一般来说,最好使用总是引用(单引号字符)的jq程序,因为太多的字符与特殊 jq 的含义也是shell元字符。在 jq 中使用单引号字符程序和反斜杠转义的双引号(\")程序举例如下。
	Unix shell: jq '.["foo"]'
	Powershell: jq '.[\"foo\"]'
	Windows命令 shell: jq ".[\"foo\"]"
	# 注意:jq允许用户自定义函数, 但每个 jq 程序必须有一个顶级表达式。

下载离线安装包

官方 --- Download Package --- jq


安装

py 复制代码
# Python 解析 json 数据
pip3 install yq
# Linux 安装
yum -y install jq
dnf -y install jq
apt-get install jq
# Mac 安装
brew install jq
# Win 安装 
scoop install jq

源码包安装

shell 复制代码
git clone --recursive https://github.com/jqlang/jq.git
cd jq
autoreconf -i
./configure
make
sudo make install

选项及含义

选项 含义
-c 压缩为一行输出,默认情况下,jq会漂亮地打印JSON输出。
-r 输出原始字符串,而非json格式字符串,【去除引号】
-M 禁用颜色, 默认终端可以强制它产生颜色
--tab 每个缩进级别使用一个制表符,而不是两个空格
--indent n 指定给定数量的空格(不超过7)进行缩进, 默认缩进空格为 2 个
-f``/`-from-file 从文件中读取筛选器,可使用"#"来进行注释

JQ 程序代码演示在线平台

JQ Command Line --- 代码演示在线平台

JQ 语法

基本过滤器

身份运算符 --- .

shell 复制代码
最简单的过滤器是`.`。 该过滤器将其输入并产生与输出相同的值。 就是这个是身份运算符
# 注意: jq 默认会漂亮地打印所有输出, 一个只包含 `.` 的程序可以用来格式化 JSON输出。类似于 curl。

代码演示 -- 折叠

[root@localhost ~]# cat > dd.json << EOF
"Hello, world! 你好,世界!"
EOF
[root@localhost ~]# cat dd.json | jq '.' 
"Hello, world! 你好,世界!"
[root@localhost ~]# 
[root@localhost ~]# cat > dd.json << EOF
0.12345678901234567890123456789
EOF
[root@localhost ~]# 
[root@localhost ~]# cat dd.json | jq '.' 
0.12345678901234567890123456789

标识符-索引 --- .foo`, `.foo.bar

shell 复制代码
	最简单且有用的过滤器类似形式 `.foo`。当给定一个 JSON对象(又名字典或哈希)作为输入时, `.foo` 表示键"foo"处的值, 如果键不存在,则为null。
形式为.foo.bar的过滤器等效于.foo | .bar
# 注意: 键名是由字母、数字、下划线组成的字符串,且开头必须为字母或下划线, 且不得包含中文;

代码演示 -- 折叠

[root@localhost ~]# cat > dd.json << EOF 
{"_name": "fd中", "23ff": 24, "age": "dd", "sal$": 100, "结果是": true, "is": false}
EOF
[root@localhost ~]# cat dd.json | jq .age  
"dd"
[root@localhost ~]# cat dd.json | jq ._name 
"fd中"
[root@localhost ~]# cat dd.json | jq '._name' 
"fd中"
[root@localhost ~]# cat dd.json | jq '.23ff'    # 语法报错
[root@localhost ~]# cat dd.json | jq '.结果是'   # 语法报错
[root@localhost ~]# cat dd.json | jq ".sal$"    # 语法报错
[root@localhost ~]# cat dd.json | jq '.is'
false

对象索引 --- .[<string>]

shell 复制代码
该语法为查找对象, 
.["foo"](上面的.foo是这个的简写版本,但是仅用于类似标识符的字符串)。

数组索引 --- .[<number>]

shell 复制代码
数组从 0 开始为它的每一个元素顺序创建下标索引,直到总长度减一。要访问它的某个元素,以方括号加下标值的方式即可;
允许使用负索引, -1 表示最后一个元素,-2 表示倒数第二个元素,依此类推;

代码演示 -- 折叠

[root@localhost ~]# cat > ee.json << EOF 
> ["a","b","c","d","e"]
> EOF
[root@localhost ~]# cat ee.json | jq .[2]
"c"
[root@localhost ~]# cat ee.json | jq .[5]
null
[root@localhost ~]# cat ee.json | jq .[-1]
"e"

数组/字符串切片 --- .[<number>:<number>]

py 复制代码
`[start:end]` 
切片指的是对序列进行截取,选取序列中的某一段。
以冒号分割索引,start代表起点索引,end代表结束点索引。省略start表示以0开始,省略end表示到列表的结尾。
# 注意: 区间是左闭右开的。也就是说[1:4]会截取列表的索引为1/2/3的3个元素,不会截取索引为4的元素。
如果提供的是负整数下标,则从列表的最后开始往头部查找。例如-1表示最后一个元素,-3表示倒数第三个元素。
# 注意: 该切片过程中不可以设置步长。

代码演示 -- 折叠

[root@localhost ~]# cat > ff.json << EOF 
> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> EOF
[root@localhost ~]# cat ff.json | jq .[2:5] -c  
[3,4,5]
[root@localhost ~]# cat ff.json | jq .[:5] -c  
[1,2,3,4,5]
[root@localhost ~]# cat ff.json | jq .[2:] -c  
[3,4,5,6,7,8,9,10]
[root@localhost ~]# cat ff.json | jq .[-3:] -c  
[8,9,10]
[root@localhost ~]# cat ff.json | jq .[:-3] -c  
[1,2,3,4,5,6,7]
[root@localhost ~]# cat ff.json | jq .[-1] -c  
10

数组/对象值迭代器 --- .[]

py 复制代码
在使用 `.[index]` 即数组索引语法时, 但若是省略索引,它将迭代该数组产生一个一个的独立的结果,而不是作为一个完整结果;
# 注意: 当数组为空时,`.[]` 的结果为  none ; 

代码演示 -- 折叠

[root@localhost ~]# cat > ff.json << EOF 
> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> EOF
[root@localhost ~]# cat ff.json | jq .[] 
1
2
3
4
5
6
7
8
9
10  
[root@localhost ~]# cat > gg.json << EOF
[{"name":"JSON", "good":true}, {"name":"XML", "habby":[11,22,33]}]
EOF
[root@localhost ~]# cat gg.json | jq .[] -c  
{"name":"JSON","good":true}
{"name":"XML","habby":[11,22,33]}
[root@localhost ~]# cat gg.json | jq .[1].habby
[
  11,
  22,
  33
]
[root@localhost ~]# cat gg.json | jq .[1].habby[]
11
22
33

逗号 --- ,

shell 复制代码
该语法为多个过滤器之间的分隔符; 
如果两个过滤器之间用逗号分隔, 则相同的输入将分别进入到两个过滤器, 而输出也将按顺序单独输出。 

代码演示 -- 折叠

[root@localhost ~]# cat > hh.json << EOF 
{"foo": 42, "bar": "something else", "projects": [11,22,33,44,55]}
EOF
[root@localhost ~]# 
[root@localhost ~]# cat hh.json | jq '.foo, .bar'   
42
"something else"
[root@localhost ~]# 
[root@localhost ~]# cat hh.json | jq '.foo, .projects[]'   
42
11
22
33
44
55
[root@localhost ~]# 
[root@localhost ~]# cat hh.json | jq '.foo, .projects[0,4]'   
42
11
55

管道 --- |

shell 复制代码
该运算符通过将左边的输出 当做是 右边的输入, 类似于 Unix shell的管道符号, 作用大致一样;
.a | . | .b 与.a.b 是等价的 

代码演示 -- 折叠

[root@localhost ~]# cat > ii.json << EOF 
[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
EOF
[root@localhost ~]# cat ii.json | jq '.[] | .name'  
"JSON"
"XML"

括号 --- ()

shell 复制代码
括号作为一个分组操作符,就像在任何典型的 编程语言;

代码演示 -- 折叠

[root@localhost ~]# cat > jj.json << EOF 
1                                                           
EOF
[root@localhost ~]# cat jj.json | jq '(. + 2) * 5'  
15

数据类型

数组 --- []

shell 复制代码
与JSON一样,[]用于构造数组, 索引从 0 开始,负索引从 -1 开始;

代码演示 -- 折叠

root@localhost ~]# cat > kk.json << EOF 
> [1, 2, 3, 4, 5, 6]
> EOF
[root@localhost ~]# cat kk.json | jq '[ .[] | . * 2]' -c   
[2,4,6,8,10,12]
[root@localhost ~]# cat > ll.json << EOF 
{"con": "china", "bar": "something else", "projects": [11,22,33,44,55]}
EOF
[root@localhost ~]# cat ll.json | jq '[.con, .projects[]]' -c  
["china",11,22,33,44,55]

字典 --- {}

shell 复制代码
与JSON类似,{}用于构造对象(也称为 字典或散列),如:{"a": 42, "b": 17}。
# 注意: 键名是由字母、数字、下划线组成的字符串,且开头必须为字母或下划线, 且不得包含中文;

代码演示 -- 折叠

[root@localhost ~]# cat > mm.json << EOF
> {"user":"stedolan","titles":["JQ Primer", "More JQ"]}
> EOF
[root@localhost ~]# 
[root@localhost ~]# cat mm.json | jq '{user, title: .titles[]}'
{
  "user": "stedolan",
  "title": "JQ Primer"
}
{
  "user": "stedolan",
  "title": "More JQ"
}
[root@localhost ~]# cat mm.json | jq '{(.user): .titles}'
{
  "stedolan": [
    "JQ Primer",
    "More JQ"
  ]
}

内置运算符

shell 复制代码
内置运算符: + , - , * , / , % 
x % y计算 x 模 y

内置函数

shell 复制代码
abs     # 对于数字输入,计算绝对值
length  # 获取各种长度,对与不同数据类型,数组计算长度,字符串计算字符个数;
map     # 将表达式映射应用于输入数组或对象中的每个值
del     # 删除数组或字典中的元素
has     # 判断返回输入字典或列表中是否具有给定的键
。。。。。。  有很多和  python 中的内置函数一致; 

参考演示数据 --- suosuo.json

py 复制代码
# 压缩为一行数据显示
[{"name":"suosuo","age":106,"is marry":"0","url":"http://mirrors.suosuo1930.com","salary":"100 million","address":{"city001":"新疆 -- 沙雅","city002":"新疆 -- 库车","city003":"吉林 -- 长春","city004":"浙江 -- 杭州"},"commit":{"author":{"name":"itchyny","email":["it@.co.jp","it@.dd.jp","it@.cc.jp"],"date":"2023-12-19T08:54:53Z","verifi":{"verified":true,"reason":"valid"}}},"arrayBrowser":[{"name":"Google","url":"http://www.google.com"},{"name":"Baidu","url":"http://www.baidu.com"}]},{"name":"雯雯","age":101,"is marry":"1","url":"http://www.wenwen.com","salary":"200 million","address":{"city001":"河南 -- 郑州","city002":"河北 -- 雄安","city003":"山东 -- 曲阜","city004":"浙江 -- 嘉兴"},"commit":{"author":{"name":"dependabot[bot]","email":["+depen@github.com","+depen@ee.com","+depen@ff.com"],"date":"2023-12-18T14:18:47Z","verifi":{"verified":true,"reason":"invalid"}}},"arrayBrowser":[{"name":"bing","url":"http://www.bing.com"},{"name":"Tshihua","url":"http://www.Tshihua.com"}]},{"name":"楠楠","age":99,"is marry":"0","url":"http://cn.nannan.com","salary":"300 million","address":{"city001":"新疆 -- 阿克苏","city002":"浙江 -- 绍兴","city003":"安徽 -- 黄山","city004":"南极 -- 特拉盖"},"commit":{"author":{"name":"github-actions[bot]","email":["+act@noreply.com","+act@gg.com","+act@hh.com"],"date":"2023-12-13T19:52:03Z","verifi":{"verified":false,"reason":"valid"}}},"arrayBrowser":[{"name":"PKU","url":"https://www.pku.edu.cn/"},{"name":"Docker","url":"https://docs.docker.com/engine/install/centos/"}]}]
py 复制代码
# JSON	数据书写规范
1. 字典中最后一对 key--value 对不可以加 逗号,其他对最后必须加 逗号,表示元素的分隔;
2. 列表同理,以 逗号 分隔每一个元素,且最后一个元素后不可以加 逗号

参考命令

打印

py 复制代码
# 格式化输出 json 数据

参考演示代码示例 -- 折叠

root@localhost ~]# cat suosuo.json | jq .
[
    {
        "name": "suosuo",
        "age": 106,
        "is marry": "0",
        "url": "http://mirrors.suosuo1930.com",
        "salary": "100 million",
        "address": {
            "city001": "新疆 -- 沙雅",
            "city002": "新疆 -- 库车",
            "city003": "吉林 -- 长春",
            "city004": "浙江 -- 杭州"
        },
        "commit": {
            "author": {
                "name": "itchyny",
                "email": [
                    "it@.co.jp",
                    "it@.dd.jp",
                    "it@.cc.jp"
                ],
                "date": "2023-12-19T08:54:53Z",
                "verifi": {
                    "verified": true,
                    "reason": "valid"
                }
            }
        },
        "arrayBrowser": [
            {
                "name": "Google",
                "url": "http://www.google.com"
            },
            {
                "name": "Baidu",
                "url": "http://www.baidu.com"
            }
        ]
    },
    {
        "name": "雯雯",
        "age": 101,
        "is marry": "1",
        "url": "http://www.wenwen.com",
        "salary": "200 million",
        "address": {
            "city001": "河南 -- 郑州",
            "city002": "河北 -- 雄安",
            "city003": "山东 -- 曲阜",
            "city004": "浙江 -- 嘉兴"
        },
        "commit": {
            "author": {
                "name": "dependabot[bot]",
                "email": [
                    "+depen@github.com",
                    "+depen@ee.com",
                    "+depen@ff.com"
                ],
                "date": "2023-12-18T14:18:47Z",
                "verifi": {
                    "verified": true,
                    "reason": "invalid"
                }
            }
        },
        "arrayBrowser": [
            {
                "name": "bing",
                "url": "http://www.bing.com"
            },
            {
                "name": "Tshihua",
                "url": "http://www.Tshihua.com"
            }
        ]
    },
    {
        "name": "楠楠",
        "age": 99,
        "is marry": "0",
        "url": "http://cn.nannan.com",
        "salary": "300 million",
        "address": {
            "city001": "新疆 -- 阿克苏",
            "city002": "浙江 -- 绍兴",
            "city003": "安徽 -- 黄山",
            "city004": "南极 -- 特拉盖"
        },
        "commit": {
            "author": {
                "name": "github-actions[bot]",
                "email": [
                    "+act@noreply.com",
                    "+act@gg.com",
                    "+act@hh.com"
                ],
                "date": "2023-12-13T19:52:03Z",
                "verifi": {
                    "verified": false,
                    "reason": "valid"
                }
            }
        },
        "arrayBrowser": [
            {
                "name": "PKU",
                "url": "https://www.pku.edu.cn/"
            },
            {
                "name": "Docker",
                "url": "https://docs.docker.com/engine/install/centos/"
            }
        ]
    }
]
py 复制代码
# 需注意以下几点: 
1. 不管是 列表 还是 字典, 在最后一个元素后不可添加 逗号 `,`;

去除引号

shell 复制代码
[root@localhost demo01]# cat suosuo.json | jq .[0] | jq .arrayBrowser[0].name
"Google"
[root@localhost demo01]# cat suosuo.json | jq .[0] | jq .arrayBrowser[0].name -r
Google

元素获取

当一级元素并列存在2个或2个以上的字典时

shell 复制代码
[root@localhost demo01]# cat demo.json | jq .
{
  "name": "suosuo",
  "age": 200
}
{
  "name": "pingping",
  "age": 300,
  "salary": "100k"
}
[root@localhost demo01]# cat demo.json | jq .name
"suosuo"
"pingping"
[root@localhost demo01]# cat demo.json | jq .salary
null
"100k"
[root@localhost demo01]# cat demo.json | jq .dddd
null
null
  1. 匹配某一个 key 时,会在每个字典中匹配
  2. 当 key 不存在时,value 为 null

当一级元素并列存在2个或2个以上的列表时

shell 复制代码
[root@localhost demo01]# cat demo02.json | jq .
[
  "100",
  "200"
]
[
  "300",
  "400"
]
[root@localhost demo01]# cat demo02.json | jq .[0]
"100"
"300"
[root@localhost demo01]# cat demo02.json | jq .[3]
null
null
[root@localhost demo01]# cat demo02.json | jq .[-1:]
[
  "200"
]
[
  "400"
]
  1. 根据索引获取元素时,会在每个列表中匹配
  2. 当 索引元素 不存在时,value 为 null

当一级元素为一个列表【数组】时 -- 根据索引获取元素

py 复制代码
[root@localhost ~]# cat suosuo.json | jq .[0]

执行结果 -- 折叠

{
  "name": "suosuo",
  "age": 106,
  "is marry": "0",
  "url": "http://mirrors.suosuo1930.com",
  "salary": "100 million",
  "address": {
    "city001": "新疆 -- 沙雅",
    "city002": "新疆 -- 库车",
    "city003": "吉林 -- 长春",
    "city004": "浙江 -- 杭州"
  },
  "commit": {
    "author": {
      "name": "itchyny",
      "email": [
        "it@.co.jp",
        "it@.dd.jp",
        "it@.cc.jp"
      ],
      "date": "2023-12-19T08:54:53Z",
      "verifi": {
        "verified": true,
        "reason": "valid"
      }
    }
  },
  "arrayBrowser": [
    {
      "name": "Google",
      "url": "http://www.google.com"
    },
    {
      "name": "Baidu",
      "url": "http://www.baidu.com"
    }
  ]
}
  1. 数组索引从 0 开始

当一级元素为一个字典时 -- 根据 Key 获取 Value

shell 复制代码
[root@localhost ~]# cat suosuo.json | jq .[0].name  
"suosuo"
[root@localhost ~]# cat suosuo.json | jq .[0].address  
{
  "city001": "新疆 -- 沙雅",
  "city002": "新疆 -- 库车",
  "city003": "吉林 -- 长春",
  "city004": "浙江 -- 杭州"
}
[root@localhost ~]# cat suosuo.json | jq .[0].address.city003  
"吉林 -- 长春"
[root@localhost ~]# cat suosuo.json | jq .[0].arrayBrowser
[
  {
    "name": "Google",
    "url": "http://www.google.com"
  },
  {
    "name": "Baidu",
    "url": "http://www.baidu.com"
  }
]
[root@localhost ~]# cat suosuo.json | jq .[0].arrayBrowser[0]
{
  "name": "Google",
  "url": "http://www.google.com"
}
[root@localhost ~]# cat suosuo.json | jq .[0].arrayBrowser[0].name  
"Google"

# 解决方法 --- 待之后解答
[root@localhost ~]# cat suosuo.json | jq .[0].arrayBrowser.[0]
jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
.[0].arrayBrowser.[0]                  
jq: 1 compile error
  1. 获取字典元素,使用 点 . 调用的方式
  2. 对于字典多层嵌套内部键值数据的获取,可使用连续 点 . 调用的方式

场景代码示例

获取硬盘分区

shell 复制代码
sfdisk -J /dev/sda | jq .partitiontable.partitions[2].node

获取所有硬盘设备名 --- lsblk

py 复制代码
[root@localhost ~]# lsblk -d -n -J | jq .blockdevices[].name -r       
sda
nvme0n1
nvme0n2

获取 Docker 容器网络配置

py 复制代码
[root@localhost ~]# docker inspect <容器名> | jq .[0].NetworkSettings.IPAddress -r   
172.17.0.2

高级用法示例

赋值

shell 复制代码
[root@localhost ]# cat kk.json  
{
  "name": "suosuo"
}
[root@localhost ]# jq .name="[1,3,4]" kk.json  | jq  .  
{
  "name": [
    1,
    3,
    4
  ]
}

对结果重定向

shell 复制代码
jq .name="[1,3,4]" kk.json  | jq -c  .  > jj.json  
# 转义: 不可再重定向到自身文件,若想更新自身文件,可通过重定向到中间文件,再覆盖到自身文件
[root@localhost ]# cat jj.json
{"name":[1,3,4]}

字典的构造

shell 复制代码
[root@localhost ~]# cat suosuo.json | jq .[0] | jq '{city002: .address.city002, reason: .commit.author.verifi.reason}'   
{
  "city002": "新疆 -- 库车",
  "reason": "valid"
}
# 等价于如下过滤器
[root@localhost ~]# cat suosuo.json | jq '.[0] | {city002: .address.city002, reason: .commit.author.verifi.reason}' 
{
  "city002": "新疆 -- 库车",
  "reason": "valid"
}

# 使用迭代器语法 
[root@localhost ~]# cat suosuo.json | jq '.[] | {city002: .address.city002, reason: .commit.author.verifi.reason}' 
{
  "city002": "新疆 -- 库车",
  "reason": "valid"
}
{
  "city002": "河北 -- 雄安",
  "reason": "invalid"
}
{
  "city002": "浙江 -- 绍兴",
  "reason": "valid"
}

数组的构造

shell 复制代码
[root@localhost ~]# cat suosuo.json | jq '[.[] | {city002: .address.city002, reason: .commit.author.verifi.reason}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid"
  },
  {
    "city002": "河北 -- 雄安",
    "reason": "invalid"
  },
  {
    "city002": "浙江 -- 绍兴",
    "reason": "valid"
  }
]

数组构造代码示例 -- 折叠

[root@localhost ~]# cat suosuo.json | jq '[.[] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: [.commit.author.email]}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": [
      [
        "it@.co.jp",
        "it@.dd.jp",
        "it@.cc.jp"
      ]
    ]
  },
  {
    "city002": "河北 -- 雄安",
    "reason": "invalid",
    "email": [
      [
        "+depen@github.com",
        "+depen@ee.com",
        "+depen@ff.com"
      ]
    ]
  },
  {
    "city002": "浙江 -- 绍兴",
    "reason": "valid",
    "email": [
      [
        "+act@noreply.com",
        "+act@gg.com",
        "+act@hh.com"
      ]
    ]
  }
]
[root@localhost ~]# 
[root@localhost ~]# cat suosuo.json | jq '[.[] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: [.commit.author.email[0]]}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": [
      "it@.co.jp"
    ]
  },
  {
    "city002": "河北 -- 雄安",
    "reason": "invalid",
    "email": [
      "+depen@github.com"
    ]
  },
  {
    "city002": "浙江 -- 绍兴",
    "reason": "valid",
    "email": [
      "+act@noreply.com"
    ]
  }
]
[root@localhost ~]#
[root@localhost ~]# cat suosuo.json | jq '[.[] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: [.commit.author.email[]]}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": [
      "it@.co.jp",
      "it@.dd.jp",
      "it@.cc.jp"
    ]
  },
  {
    "city002": "河北 -- 雄安",
    "reason": "invalid",
    "email": [
      "+depen@github.com",
      "+depen@ee.com",
      "+depen@ff.com"
    ]
  },
  {
    "city002": "浙江 -- 绍兴",
    "reason": "valid",
    "email": [
      "+act@noreply.com",
      "+act@gg.com",
      "+act@hh.com"
    ]
  }
]

嵌套字典的构造

shell 复制代码
[root@localhost ~]# cat suosuo.json | jq '[.[0] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: {list: .commit.author.email}}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": {
      "list": [
        "it@.co.jp",
        "it@.dd.jp",
        "it@.cc.jp"
      ]
    }
  }
]


[root@localhost ~]# cat suosuo.json | jq '[.[] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: {list: .commit.author.email}}]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": {
      "list": [
        "it@.co.jp",
        "it@.dd.jp",
        "it@.cc.jp"
      ]
    }
  },
  {
    "city002": "河北 -- 雄安",
    "reason": "invalid",
    "email": {
      "list": [
        "+depen@github.com",
        "+depen@ee.com",
        "+depen@ff.com"
      ]
    }
  },
  {
    "city002": "浙江 -- 绍兴",
    "reason": "valid",
    "email": {
      "list": [
        "+act@noreply.com",
        "+act@gg.com",
        "+act@hh.com"
      ]
    }
  }
]

嵌套列表的构造

shell 复制代码
[root@localhost ~]# cat suosuo.json | jq '[.[0] | {city002: .address.city002, reason: .commit.author.verifi.reason, email: [.commit.author.email[]]}, "sfsfsf"]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "email": [
      "it@.co.jp",
      "it@.dd.jp",
      "it@.cc.jp"
    ]
  },
  "sfsfsf"
]

[root@localhost ~]# cat suosuo.json | jq '[.[0] | {city002: .address.city002, reason: .commit.author.verifi.reason}, [.commit.author.email[]]]' 
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid"
  },
  [
    "it@.co.jp",
    "it@.dd.jp",
    "it@.cc.jp"
  ]
]

[root@localhost ~]# cat suosuo.json | jq '[.[0] | {city002: .address.city002, reason: .commit.author.verifi.reason, age: "999"}, [.commit.author.email[]]]'   
[
  {
    "city002": "新疆 -- 库车",
    "reason": "valid",
    "age": "999"
  },
  [
    "it@.co.jp",
    "it@.dd.jp",
    "it@.cc.jp"
  ]
]

参考网址

JSON 在线格式化或解析平台

官方手册 --- jq Manual