Middleware ❀ JSON数据格式与格式化操作详解

news/2024/12/29 7:53:19/

文章目录

  • 1. JSON数据格式详解
    • 1.1 两种结构
    • 1.2 使用范例
  • 2. jq
    • 2.1 安装
    • 2.2 jq 基础使用
      • 2.2.1 基本语法
      • 2.2.2 基础使用
        • 2.2.2.1 测试环境准备
        • 2.2.2.2 基础字段解析
        • 2.2.2.3 列表、迭代器、管道
        • 2.2.2.4 复杂数据类型构建
        • 2.2.2.5 内置的操作符以及函数
  • 3. python -m json.tool

1. JSON数据格式详解

JSON(JavaScript Object Notation))是一种轻量级的数据交换格式。 便于人为阅读和编写、机器解析和生成。

1.1 两种结构

  • 对象:是一个无序的 key/value 键值对集合,一个对象以 {开始,以}结束,每个key后面跟一个:, key/value 键值对之间使用,分隔;
  • 数组:是value的有序集合,一个数组以[开始,以]结束,value之间使用,分隔;value可以是双引号内的字符串、数值、TRUE、FALSE、NULL、对象或数组;

1.2 使用范例

# 压缩
{"key1":"value1","key2":["key3","key4",{"key5":"value5","key6":"value6"}]}# 格式化
{"key1": "value1","key2": ["key3", "key4", {"key5": "value5","key6": "value6"}]
}

2. jq

jq是stedolan开发的一个轻量级的和灵活的命令行JSON处理器,它主要用于在命令行界面处理JSON输入,并使用给定的过滤条件来过滤符合条件的新的JSON串。通常使用jq来进行JSON数据格式化过滤和处理。

2.1 安装

$ yum install jq

2.2 jq 基础使用

2.2.1 基本语法

$ jq [options] <jq filter> [file...]
$ jq [options] --args <jq filter> [strings...]
$ jq [options] --jsonargs <jq filter> [JSON_TEXTS...]# options 可选参数列表和说明
-c               将格式化json输出为紧凑的字符串格式;
-n               使用`null`作为单个输入值;
-e               根据输出设置退出状态代码;
-s               将所有输入读取(吸取)到数组中;应用过滤器;
-r               输出原始字符串,而不是JSON文本;
-R               读取原始字符串,而不是JSON文本;
-C               为JSON输出填充颜色;
-M               单色(不要为JSON着色);
-S               在输出上排序对象的键;
--tab            使用制表符进行缩进;
--arg a v        将变量$a设置为value<v>;
--argjson a v    将变量$a设置为JSON value<v>;
--slurpfile a f  将变量$a设置为从<f>读取的JSON文本数组;
--rawfile a f    将变量$a设置为包含<f>内容的字符串;
--args           其余参数是字符串参数,而不是文件;
--jsonargs       其余的参数是JSON参数,而不是文件;
--               终止参数处理;# 查看更多使用指南。
$ jq --help

2.2.2 基础使用

2.2.2.1 测试环境准备

$ mkdir json
$ cd json/
$ echo '{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"pc-deployment","namespace":"dev"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx-pod"}},"template":{"metadata":{"labels":{"app":"nginx-pod"}},"spec":{"containers":[{"name":"nginx","image":"nginx:1.17.1","ports":[{"containerPort":80}]}]}}}}' > ./test.json

2.2.2.2 基础字段解析

# 使用.参数默认格式化整个json数据
$ cat test.json | jq .				# 单独出现的"."可以省略
{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "pc-deployment","namespace": "dev"},"spec": {"replicas": 3,"selector": {"matchLabels": {"app": "nginx-pod"}},"template": {"metadata": {"labels": {"app": "nginx-pod"}},"spec": {"containers": [{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}]}}}
}# 使用.$key来获取指定value
$ cat test.json | jq .apiVersion
"apps/v1"# 解析json中的层级数据
$ cat test.json | jq .spec
{"replicas": 3,"selector": {"matchLabels": {"app": "nginx-pod"}},"template": {"metadata": {"labels": {"app": "nginx-pod"}},"spec": {"containers": [{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}]}}
}
# 仅输出某个层级下的数据
$ cat test.json | jq .spec.selector.matchLabels.app
"nginx-pod"# 获取多个字段 (使用'.filed1,.filed2' 可以获取两个字段)
$ cat test.json | jq .spec.selector.matchLabels.app,.spec.template.metadata.labels.app,.spec.template.spec.containers[].ports[].containerPort
"nginx-pod"
"nginx-pod"
80

2.2.2.3 列表、迭代器、管道

# 解析json中的数组或者列表
$ cat test.json | jq .spec.template.spec.containers
[{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}
]# 支持索引检查,比如.array[index],索引从0开始,-n为倒数第n个元素
$ cat test.json | jq .spec.template.spec.containers[0]
{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]
}
# 支持索引范围检查,比如.array[index_src:index_dst]
cat test.json | jq .spec.template.spec.containers[0:3]
[{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}
]# value迭代器.[],[]为全部范围,此时可以省略
$ cat test.json | jq .spec.template.spec.containers[]
{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]
}# 管道,在jq的表达式中,可以使用管道符号"|"来对前面的表达式结果进行再次处理
$ cat test.json | jq '.spec.template.spec.containers[]|.name'
"nginx"
# 使用管道符合时必须使用引号,否则Linux会识别为命令
$ cat test.json | jq .spec.template.spec.containers[]|.name 
bash: .name: command not found...# 值的计算 
echo '{"num":12}' | jq '(.num +2)*1024'
14336

2.2.2.4 复杂数据类型构建

  • 列表 (数组) 构建 []: 可以将输出字符返回成一个列表 (可以结合多字段使用)

  • 对象构建 {}: 可以联合()构建新的 json 对象

    • {} 可以通过字段构建新的 json 结构,比如 {user, title: .titles[]} 表示将 titles 数组中的元素迭代出来后和 user 字段重新组成多个 json 字串
    • () 可以用于直接将 value 作为 key,比如 {(.user): .titles} 可以直接构建无声明 key 的 json 串
  • 递归下降..: 可以递归下降,将字符串的每一个 value 都迭代出来,用法和内置的 recurse 函数相似

# 数组构建
$ cat test.json | jq '[.spec.selector]'
[{"matchLabels": {"app": "nginx-pod"}}
]$ cat test.json | jq [.spec.replicas,.spec.template.metadata.labels.app]
[3,"nginx-pod"
]# 批量计算
$ echo '{"num": [1,2,3,4]}' | jq '[.num[] | . * 2 ]'
[2,4,6,8
]# 对象构建
$ cat test.json | jq '{apiVersion,kind,name:.spec.template.spec.containers[].name,image:.spec.template.spec.containers[].image}'
{"apiVersion": "apps/v1","kind": "Deployment","name": "nginx","image": "nginx:1.17.1"
}# 构建无声明key的json数据,key = (.kind)
$ cat test.json | jq '{apiVersion,name:.spec.template.spec.containers[].name,(.kind):.spec.template.spec.containers[].image}'
{"apiVersion": "apps/v1","name": "nginx","Deployment": "nginx:1.17.1"
}# 递归下降,使用..可以将全部的子串解析出来,直到最后的叶子value
$ echo '[[{"a":1}]]' | jq '.. '
[[{"a": 1}]
]
[{"a": 1}
]
{"a": 1
}
1# 递归下降获取具体的值'.. | .filed',获取key包含a的值
$ echo '[[{"a":1}]]' | jq '.. | .a?'
1

2.2.2.5 内置的操作符以及函数

  • +:两个过滤器相加,支持Numbers、Arrays、Strings、Objects类型;

  • -:相减,用法同上;

  • *,/,%:乘除余运算;

  • length:获取不同类型值的长度,支持string,array,object,null(zero);

  • utf8bytelength:utf8的字节长度;

  • keyskeys_unsorted: 获取最外层的key以及排序之后的key,如果是列表或者数组,将返回索引;

  • has(key):返回json中是否包含key,或者数组/列表中是否包含索引下标(需要注意的是,如果需要解析

    析数组/列表内部的子串是否包含某个key,需要先使用map函数;

  • in(object): 判断json中是否包含object中给定的key;

  • max(x)map_values(x): 使用过滤器x对输入数组的元素进行挨个计算,并返回新数组;后者是给值进行计算;

  • path(path_expression): 输出给定路径表达式中的数组表示;

  • del(path_expression): 删除路径表达式中的filed;

  • getpath(PATHS): 获取指定路径的索引;

  • setpath(PATHS; VALUE): 给指定路径设置新的值;

  • delpaths(PATHS): 删除指定路径;

  • to_entries, from_entrieswith_entries: 二次处理 json 实体,比如从[{key:k1,value: v1}{key:k2,value:v2} ] 转换成 {k1:v1,k2:v2}

  • select(boolean_expression):使用bool表达式进行条件过滤;

  • arrays objectsiterablesbooleansnumbersnormalsfinitesstringsnullsvalues, scalars:分别只选择数组、对象、可迭代对象 (数组或对象)、布尔值、数字、普通数字、有限数字、字符串、空值、非空值和不可迭代对象的输入;

  • add: 过滤器 add 接受一个数组作为输入,并将数组的元素加在一起作为输出。这可能意味着根据输入数组元素的类型进行求和、连接或合并 —— 规则与上面描述的+运算符的规则相同;

  • anyall:从数组或者列表中判断是否存在或者全部存在;

  • range:对象生成器;

  • floor:输出数字的低阶值;

  • sqrt:求开方;

  • tonumber:字符串转数字;

  • tostring:数字转字符串;

  • type: 获取元素类型;

  • sortsort_by(path_expression):排序;

  • unique, unique_by(path_exp):去重;

  • reverse:反转;

  • contains(element):判断是否包含;

  • startswith(str):判断前缀;

  • endswith(str):判断后缀;

  • split(str):字符串转列表;

  • join(str):列表转字符串;

  • while(cond; update):条件判断;

  • until(cond; next):条件判断;

  • (foo):引用 foo 的值;

  • tojsonfromjson:从原始字符串转到 json 或者从 json 转到原始字符串;

  • @base64@base64d:base64 编码和解码;

  • @uri@csv:生成 uri,以及表格格式。

# keys
$ cat test.json | jq 'keys'
["apiVersion","kind","metadata","spec"
]# keys_unsorted
$ cat test.json | jq 'keys_unsorted'
["apiVersion","kind","metadata","spec"
]# has
$ cat test.json | jq '.spec | has("replicas")'
true$ cat test.json | jq 'has("replicas")'
false
$ cat test.json | jq 'has("spec")'
true# to_entries, from_entries, with_entries
$ cat test.json | jq '.spec | to_entries'
[{"key": "replicas","value": 3},{"key": "selector","value": {"matchLabels": {"app": "nginx-pod"}}},{"key": "template","value": {"metadata": {"labels": {"app": "nginx-pod"}},"spec": {"containers": [{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}]}}}
]# select(bool_exp)
$ cat test.json | jq '. | select(.kind == "Deployment")'
{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "pc-deployment","namespace": "dev"},"spec": {"replicas": 3,"selector": {"matchLabels": {"app": "nginx-pod"}},"template": {"metadata": {"labels": {"app": "nginx-pod"}},"spec": {"containers": [{"name": "nginx","image": "nginx:1.17.1","ports": [{"containerPort": 80}]}]}}}
}# @base64/@base64d
$ cat test.json | jq '.apiVersion '
"apps/v1"
$ cat test.json | jq '.apiVersion | @base64'
"YXBwcy92MQ=="
$ cat test.json | jq '.apiVersion | @base64 | @base64d'
"apps/v1"

3. python -m json.tool

若Linux系统无法下载jq工具,可以使用默认python工具包中的json.tool做JSON数据格式化操作(部分操作系统使用的是python3版本),与等同于jq -M不着色显示。

$ cat test.json | python -m json.tool
{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "pc-deployment","namespace": "dev"},"spec": {"replicas": 3,"selector": {"matchLabels": {"app": "nginx-pod"}},"template": {"metadata": {"labels": {"app": "nginx-pod"}},"spec": {"containers": [{"image": "nginx:1.17.1","name": "nginx","ports": [{"containerPort": 80}]}]}}}
}

http://www.ppmy.cn/news/231823.html

相关文章

SATA硬盘接口是什么

串行高级技术附件&#xff08;串行 ATA&#xff0c;SATA 或 S-ATA&#xff09;是一种计算机总线接口&#xff0c;用hzcya于将主机总线适配器与光驱和硬盘等大容量存储设备连接。该接口通常用于将硬盘驱动器连接到主机系统&#xff0c;例如计算机主板。SATA 是对 20 世纪 80 年代…

固态硬盘连接在SATA2、SATA3接口上,使用不同SATA线的速度对比

1. 固态硬盘连接在SATA2接口上&#xff0c;使用原装STAT线&#xff08;原来连接光驱用&#xff09; 2. 固态硬盘连接在SATA2接口上&#xff0c;使用淘宝购买SATA3线 3. 固态硬盘连接在SATA3接口上&#xff0c;使用原装STAT线&#xff08;原来连接光驱用&#xff09; 4. 固态硬盘…

SATA接口是什么

串行高级技术附件&#xff08;串行 ATA&#xff0c;SATA 或 S-ATA&#xff09;是一种计算机总线接口&#xff0c;用于将主机总线适配器与光驱和硬盘等大容量存储设备连接。该接口通常用于将硬盘驱动器连接到主机系统&#xff0c;例如计算机主板。SATA 是对 20 世纪 80 年代用于…

SATA硬盘电源线或数据线引发的故障

2019独角兽企业重金招聘Python工程师标准>>> 今天修一旧电脑&#xff0c;遇到SATA硬盘老是检查不到硬盘的问题&#xff0c;后来发现是电源接口的问题&#xff0c;电源自带的好几个SATA因为老化变形&#xff0c;都不能用&#xff0c;后来换了一个大D转SATA的电源线就…

笔记本电脑如何设置网卡的自动协商功能

笔记本的网卡一般都支持自动协商协议&#xff08;Auto Negotiation Protocol&#xff09;&#xff0c;能够自动适应不同的网速和工作模式。如果你想确认自己的笔记本网卡是否支持该功能&#xff0c;可以在设备管理器中找到网卡设备&#xff0c;并查看其属性中“高级”选项卡内是…

深入认识笔记本电脑的网卡

1.12 深入认识笔记本电脑的网卡 网卡本身是局域网(LAN)中最基本的部件之一&#xff0c;通过网关、路由器等设备可以把局域网挂接到Internet上。网卡&#xff0c;又称网络卡或网络接口卡&#xff0c;英文简称为NIC (Network Interface Card)。它的主要工作原理为整理计算机上发…

关于华硕飞行堡垒8笔记本网卡启动不了(Inter(R) Wi-Fi 6 AX201)该设备无法启动 代码10

今天打开笔记本莫名奇妙的&#xff0c;连不上WIFI了&#xff0c;网线可以联网&#xff0c;查看设备管理器&#xff0c;网卡亮感叹号&#xff0c;查看详情&#xff0c;提示&#xff1a;该设备无法启动 代码10 代码10有三个情况&#xff0c; 1&#xff0c;驱动不合&#xff0c;概…

关于华硕天选2笔记本所用的mt7921网卡问题

相信各位已经经历过网卡驱动突然消失&#xff0c;网卡导致蓝屏等各种问题了&#xff0c;我找过华硕客服&#xff0c;他们在跟我说解决方法的时候居然跟我说这不是个例。华硕啊&#xff0c;你这那么严重的问题居然不告知消费者&#xff0c;这的确有点过分了…… 我先说说我的问…