# jq表达式
jq 表达式是一种用于处理 JSON 数据的语言,可以过滤、查询、修改和转换 JSON 数据,官方地址如下:
官方手册:https://stedolan.github.io/jq/manual/ (opens new window)
模拟运行:https://jqplay.org/ (opens new window)
以下是一些 jq 表达式的计算场景:
# 条件判断
# 数据比较
使用==, !=,>,>=,<=,<等符号,对布尔值、字符串、数值、对象进行比较:
输入数据:
{
"foo": false,
"str": "test",
"num": 1,
"obj": {
"b": {}
}
}
示例表达式:
.foo == false
# 输出 true
.str == "test"
# 输出 true
.num == 0
# 输出 false
.obj == {"b":{ "d": "" }}
# 输出 false
# if else
if 条件是我们常用的条件判断语法,一般语法结构是if A then B else C end,更多条件可用 elif 继续判断。
输入数据:
{
"foo": false,
"num": "1"
}
示例表达式:
if .foo then "zero" elif .num == 1 then "one" else "many" end
# 输出:one
# and、or、not
使用and,or,not操作进行布尔值的且或非运算,返回 false / true 结果。
- 如果操作符一侧为数值或字符串,视为 true
下列表达式均为 true:
42 and "str"
-1 and ""
false or true
true and false|not
# 选择操作 //
当需要判断的第一个参数为 empty、null 或为 false 时,返回第二个备选值,需要注意的是,空字符串或负数值都不符合返回备选值的条件:
表达式:empty // 42
#输出: 42
表达式:null // 42
#输出: 42
表达式:.foo // 42
输入:{"foo": 19}
#输出:19
表达式:(false, null, 1) // 42
#输出: 1
# 字符串
# 字符串拼接
输入数据:
{
"code": "test"
}
期望结果:取 code 属性的值与其他字符串进行拼接,生成新的属性。
{
"new": "test-server"
}
示例表达式
{
"new": "\(.code)-server"
}
# 数组
# 遍历数组元素设置属性
- 静态属性名
输入数据:
{
"object": {"id": "A"},
"array": [
{
"name": "B"
}
]
}
期望结果:遍历array数组每个对象,将object的id属性设置为数组对象的objectId。
[
{
"name": "B",
"objectId": "A"
}
]
示例表达式:
// 示例1
[.array[]+{objectId:.object.id}]
// 示例2:利用变量,可在深度遍历时取外层的对象属性
.object.id as $objId | [.array[]|.+{objectId:$objId}]
- 动态属性名
设遍历数组设置元素属性值的属性名,需要外部控制或动态处理,可结合as $f及"\($f)"设置,示例如下。
输入数据:
{
"refName": "customName",
"object": {"id": "A"},
"array": [
{
"name": "B"
}
]
}
期望结果:
[
{
"name": "B",
"customName": "A"
}
]
示例表达式:
.refName as $ref | .object.id as $objId | [.array[]|.+{"\($ref)":$objId}]
# 数组元素拼接成字符串
输入数据:
{
"array": ["a", "b", "c"]
}
期望结果:将数组元素拼接成字符串,以逗号分隔。
{
"result": "a,b,c"
}
示例表达式:
{
"result": (.array|join(","))
}
# 对象
# 数据合并
输入数据:
{
"object1": {
"name": "first",
"test1": "1"
},
"object2": {
"name": "second",
"test2": "2"
}
}
目的:两个对象数据合并,形成一个新的对象。
示例表达式:
.object1 + .object2
结果:
{
"name": "second",
"test1": "1",
"test2": "2"
}
根据结果可以了解到,当 key 冲突时后者覆盖前者的值,即结果中 name 的值为 object2 的 second。
# 删除对象属性
输入数据:
{
"name": "A",
"test": "B"
}
示例表达式:
del(.name)
结果:
{
"test": "B"
}
# 数据转换
# json 字符串转对象
输入数据(\为转义字符):
{
"jsonStr": "{\"test\":1}"
}
期望结果:转成对象,可取其中的属性等。
{
"test": 1
}
示例表达式:
.jsonStr|fromjson
# 字符串转数字
输入数据:
{
"numStr": "123"
}
示例表达式:
.numStr|tonumber
输出的结果是: 123
如果字符串无法转换为数字(例如包含非数字字符),tonumber 会抛出错误。可以通过 try/catch 或默认值避免工作流中断:
.numStr | try tonumber catch 0
或者是提供默认值
.numStr | tonumber? // 0
# 日期时间
获取当前日期时间(支持配置格式):
(now|strftime("yyyy-MM-dd HH:mm:ss"))
# 随机UUID
生成随机 UUID:
uuid()
# 输出: "f7b3b3b3-3b3b-4b3b-8b3b-3b3b3b3b3b3b"