文章目录
- 前言
- 一、jq简介
- 1. 简介
- 2. 语法
- 3. 命令选项
- 二、用于处理json数据
- 1. 过滤
- 1.1 标识运算符
- 1.2 基本过滤
- 1.3 获取对象属性
- 1.3 迭代数组元素
- 1.4 获取数组元素
- 1.5 使用运算符
- 2. 类型和值
- 2.1 数组构造
- 2.2 对象构造
- 2.3 递归下降
- 3. 内置运算符和函数
- 3.1 算术运算符
- 3.2 函数
- 3.2.1 length
- 3.2.2 keys和keys_unsorted
- 3.2.3 has(key)
- 3.2.4 map(f)和map_values(f)
- 3.2.5 del(path_expression)
- 3.2.6 getpath(PATHS)
- 总结
前言
本文介绍了jq工具的基本概念、语法和常用命令选项。jq是一个强大的JSON处理工具,可以帮助我们在命令行中对JSON数据进行过滤、转换和聚合等操作。通过学习本文内容,您将了解如何使用jq来提取和操作JSON数据,以及如何利用内置函数和运算符实现更复杂的处理逻辑。
一、jq简介
1. 简介
jq是一个处理JSON输入的工具,将给定的过滤器应用于其JSON文本输入,并在标准输出上以JSON形式生成过滤器的结果。
2. 语法
jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
3. 命令选项
下面是一些 jq
命令的选项:
-c
:以紧凑格式而不是漂亮的格式输出;-n
:将null
作为单个输入值使用;-e
:基于输出设置退出状态码;-s
:将所有输入读取到一个数组中,然后对其应用过滤器;-r
:输出原始字符串,而不是 JSON 文本;-R
:读取原始字符串,而不是 JSON 文本;-C
:对 JSON 进行着色;-M
:单色输出(不对 JSON 进行着色);-S
:按输出时对象的键对其进行排序;--tab
:使用制表符进行缩进;--arg a v
:将变量$a
设置为值<v>
;--argjson a v
:将变量$a
设置为 JSON 值<v>
;--slurpfile a f
:将变量$a
设置为从<f>
读取的 JSON 文本数组;--rawfile a f
:将变量$a
设置为由<f>
的内容组成的字符串;--args
:其余参数是字符串参数,而不是文件;--jsonargs
:其余参数是 JSON 参数,而不是文件;--
:终止参数处理。
命名参数也可以作为 $ARGS.named[]
使用,而位置参数可以作为 $ARGS.positional[]
使用。
二、用于处理json数据
把下面的json数据保存为demo.json
文件,将使用demo.json
文件为示例进行演示:
{
"args": {
"foo1": "bar1",
"foo2": "bar2"
},
"items": [
{
"name": "zhangsan",
"age": "18"
},
{
"name": "lisi",
"age": "19"
},
{
"name": "wangwu",
"age": "20"
}
],
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-65faa3d6-3241ccac7e16cccb6ad624df",
"user-agent": "PostmanRuntime-ApipostRuntime/1.1.0",
"cache-control": "no-cache",
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"cookie": "sails.sid=s:EwVZbX2HjXEMC_pnJ4yiHZ4_z99ZURCH.SNn1CdtJ4ufRX9qvNRioMrrjCQWG+RdFd5aXkV2PrZA",
"authorization": "Basic cG9zdG1hbjpwb3N0bWFuMTIz"
},
"url": "https://postman-echo.com/get?foo1=bar1&foo2=bar2"
}
1. 过滤
1.1 标识运算符
标识运算符是一个小数点.
,在jq
命令中,.
是一个特殊字符,表示当前JSON对象的引用。它可以用于访问和处理JSON数据的各个部分。
使用.
可以执行以下操作:
-
访问对象属性:
.property
表示获取当前对象中名为"property"的属性值。 -
迭代数组元素:
.[]
表示遍历当前数组,并返回其中每个元素。 -
过滤器操作:通过结合
.
和其他过滤器操作符(如条件、映射、折叠等),可以对JSON数据进行筛选、转换和聚合等复杂处理。例如,.[] | select(.age > 18)
会选择年龄大于18岁的所有数组元素。 -
调用函数或方法:你还可以使用
.
来调用内置函数或自定义函数,并将其应用于当前上下文中的值。例如,在一个字符串上应用.toupper()
函数将字符串转换为大写形式。
1.2 基本过滤
使用jq命令不进行过滤输出数据。
cat demo.json | jq .
如下图所示:
1.3 获取对象属性
cat demo.json | jq .args
cat demo.json | jq .args.foo1
cat demo.json | jq '.url, .args.foo1'
1.3 迭代数组元素
cat demo.json | jq .items[]
cat demo.json | jq .items[].name
cat demo.json | jq .items[] | jq .name
cat demo.json | jq '.items[] | .name'
cat demo.json | jq .items[].age
cat demo.json | jq '.items[] | "\(.name):\(.age)"'
1.4 获取数组元素
cat demo.json | jq .items[0]
cat demo.json | jq .items[1]
cat demo.json | jq .items[-1]
cat demo.json | jq .items[1,2]
cat demo.json | jq .items[0:3]
cat demo.json | jq .items[1:3]
1.5 使用运算符
cat demo.json | jq '(.items[].age + 1) * 2'
cat demo.json | jq '(.items[1].age + 1) * 2'
2. 类型和值
jq中支持与JSON相同的数据类型,包括数字、字符串、布尔值、数组和对象(在JSON中称为只有字符串键的哈希表),以及"null"。
布尔值、null、字符串和数字在jq中的写法与JSON相同。就像jq中的其他所有内容一样,这些简单值接受一个输入并产生一个输出。
在jq中,数字内部使用IEEE754双精度近似表示。对于任何涉及数字(无论是字面量还是先前过滤器结果)进行算术运算时,将生成双精度浮点数结果。
然而,在解析字面量时,如果没有对该值应用变换,则会将原始字面量字符串存储起来。如果没有对其进行转换为double操作会导致损失,则此原始形式将保留到输出结果中去。
2.1 数组构造
数组构造:[]
与JSON中一样,用于构造数组,例如 []. 数组的元素可以是任何jq表达式,包括管道。所有表达式产生的结果都会被收集到一个大数组中。
理解","运算符,就能以不同角度看待jq的数组语法:这个表达式并没有使用内置语法来表示逗号分隔的数组,而是将操作符(collect results)应用于表达式 。
示例:
cat demo.json | jq '[.args.foo1, .items[]]'
cat demo.json | jq '[.items[].age | . + 2]'
2.2 对象构造
对象构造:{}
与JSON类似,用于构造对象(也称为字典或哈希表)。如果键是"标识符样式"的,则可以省略引号。值可以是任何表达式,该值会应用于 {} 表达式的输入上。
示例:
cat demo.json | jq '{url, foo: .args.foo1}'
cat demo.json | jq '{url: .url, foo: .args.foo1}'
cat demo.json | jq '{url, name: .items[].name}'
2.3 递归下降
递归下降:…
使用递归下降运算符 …,可以逐级遍历数据结构,并产生每个值。这与零参数内置函数相同。
示例:
cat demo.json | jq '.. | .name?'
3. 内置运算符和函数
3.1 算术运算符
+ - * / %
示例:
cat demo.json | jq '.items[0].age + 2'
cat demo.json | jq '.items[0].age - 2'
cat demo.json | jq '.items[0].age * 2'
cat demo.json | jq '.items[0].age / 2'
cat demo.json | jq '.items[0].age % 5'
3.2 函数
3.2.1 length
length函数用于获取各种不同类型值的长度。
cat demo.json | jq '. | length'
cat demo.json | jq '.items | length'
cat demo.json | jq '.items[] | length'
3.2.2 keys和keys_unsorted
keys
是许多编程语言中的内置函数,用于返回对象或字典的键。当应用于对象时,它会返回一个包含该对象键的数组。这些键按照 Unicode 码点顺序进行“字母顺序”排序。
而 keys_unsorted
函数与 keys
类似,但是当输入为对象时,并不对其进行排序;相反地,在大致上保持插入顺序作为输出结果的键。
cat demo.json | jq keys
cat demo.json | jq keys_unsorted
cat demo.json | jq '.items[] | keys_unsorted'
3.2.3 has(key)
has(key)
是一个内置函数,用于判断输入对象是否具有给定的键(key),或者输入数组是否在给定索引处存在元素。
对于对象来说,调用 has(key)
函数会返回一个布尔值,表示该对象是否包含指定的键。
对于数组来说,在某个特定索引位置上使用该函数可以判断该位置上是否存在元素。它也将返回一个布尔值作为结果。
cat demo.json | jq 'has("items")'
cat demo.json | jq 'has("name")'
cat demo.json | jq '.items[] | has("name")'
3.2.4 map(f)和map_values(f)
map(f)
和map_values(f)
是两个函数,用于对输入数组或对象中的每个值应用指定的过滤器(函数)f
。它们分别相当于.[] | f
和.[] |= f
在没有错误发生的情况下,无论何时使用这些函数都会输出一个数组。如果给定一个数组作为输入,则输出也是一个数组;如果给定一个对象作为输入,则输出将是一个具有相同键但值经过处理后的新对象。
echo [18,19,20] | jq 'map(.+1)'
echo '{"a": 1, "b": 2, "c": 3}' | jq 'map(.+1)'
echo '{"a": 1, "b": 2, "c": 3}' | jq 'map_values(.+1)'
3.2.5 del(path_expression)
del
是一个内置函数,用于从对象中删除一个键及其对应的值。
echo '{"foo": 42, "bar": 9001, "baz": 42}' | jq 'del(.foo)'
3.2.6 getpath(PATHS)
内置函数输出在.getpath.PATHS
中每个路径找到的值。
cat demo.json | jq 'getpath(["args","foo1"],["args","foo2"])'
cat demo.json | jq '[getpath(["args","foo1"],["args","foo2"])]'
总结
通过学习并掌握jq工具,在命令行中高效地处理JSON数据变得轻而易举。无论是从复杂嵌套结构中提取特定字段还是对数组进行筛选与映射操作,都可以借助jq简洁而灵活地完成。通过深入理解本文介绍的标识运算符、数组构造、对象构造以及内置函数等概念,在实际应用场景中能够更加熟练地使用这些功能,并根据需要进一步扩展自己的应用程序或脚本。
希望本教程对您有所帮助!如有任何疑问或问题,请随时在评论区留言。感谢阅读!
参考链接:
- https://jqlang.github.io/jq/manual/