jq 在不破坏 json 的情况下删除内部子节点
jq removing inner child node without breaking the json
我试图让 jq 从 json 文件中删除一个内部节点,json 文件看起来是这样的:
{
"etag": "14b3796c268c87553291702c808e86dfe1e53d1b",
"rules": {
"name": "default",
"children": [
{
"name": "xxxx",
"children": [
{
"name": "dffaa42b-3f0f-425f-a9a1-a63cd35b2517",
"children": [],
"behaviors": [
{
"name": "xxx",
"options": {
"key": "xxx-xxx-xxx-xxx",
"compress": true,
"ports": ""
}
}
],
"criteria": [
{
"name": "xxxx",
"options": {
"Name": "UUID",
"values": [
"dffaa42b-3f0f-425f-a9a1-a63cd35b2517"
]
}
}
],
"criteriaMustSatisfy": "all"
},
{
"name": "7004389c-c47a-4611-9bd7-9f5dfe051d17",
"children": [],
"behaviors": [
{
"name": "xxx",
"options": {
"key": "xxx-xxx-xxx-xxx",
"compress": true,
"ports": ""
}
}
],
"criteria": [
{
"name": "xxxx",
"options": {
"Name": "UUID",
"values": [
"7004389c-c47a-4611-9bd7-9f5dfe051d17"
]
}
}
],
"criteriaMustSatisfy": "all"
}
],
"behaviors": [],
"criteria": [],
"criteriaMustSatisfy": "all"
}
],
"behaviors": [
{
"name": "xxx",
"options": {}
}
],
"options": {
"is_secure": true
},
"variables": []
},
"warnings": [
],
"Format": "xxx"
}
我可能搞错了json结构,但是我现在的jq查询如下:
(.rules.children[].children[] | select(.name | contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")| not ))
这有效,除了 return json 从 .rules.children[].children[]
中排除子项目。
如何让 jq return 整个 json 文件排除过滤器中识别的 json?
del/1
可以根据路径表达式删除节点
这个例子似乎不是最小的,所以让我们考虑一下:
{"a":{"c":[
{"d":{"c":[{"e":"xyzzy"},{"e":2}]}},
{"d":{"c":[{"e":"xyzzy"},{"e":2}]}} ]}}
现在假设我们要删除 .e == "xyzz"
:
的对象
del( .a.c[].d.c[] | select(.e == "xyzzy") )
这将导致:
{"a":{"c":[{"d":{"c":[{"e":2}]}},{"d": {"c":[{"e":2}]}}]}}
很遗憾,jq 1.5不支持del/1
中的复杂路径规范;然而,使用足够新的 jq 版本,我们可以写:
del( .a.c[].d.c[] | select(.e | type == "string" and contains("xyzzy") ) )
因此,对于 jq 1.5 的 above-mentioned 警告,您可以这样写:
del(.rules.children[].children[] | select(.name| contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")))
jq 1.5 的解决方法
.rules.children[].children |=
map(select((.name? // "")
| contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")
| not))
我试图让 jq 从 json 文件中删除一个内部节点,json 文件看起来是这样的:
{
"etag": "14b3796c268c87553291702c808e86dfe1e53d1b",
"rules": {
"name": "default",
"children": [
{
"name": "xxxx",
"children": [
{
"name": "dffaa42b-3f0f-425f-a9a1-a63cd35b2517",
"children": [],
"behaviors": [
{
"name": "xxx",
"options": {
"key": "xxx-xxx-xxx-xxx",
"compress": true,
"ports": ""
}
}
],
"criteria": [
{
"name": "xxxx",
"options": {
"Name": "UUID",
"values": [
"dffaa42b-3f0f-425f-a9a1-a63cd35b2517"
]
}
}
],
"criteriaMustSatisfy": "all"
},
{
"name": "7004389c-c47a-4611-9bd7-9f5dfe051d17",
"children": [],
"behaviors": [
{
"name": "xxx",
"options": {
"key": "xxx-xxx-xxx-xxx",
"compress": true,
"ports": ""
}
}
],
"criteria": [
{
"name": "xxxx",
"options": {
"Name": "UUID",
"values": [
"7004389c-c47a-4611-9bd7-9f5dfe051d17"
]
}
}
],
"criteriaMustSatisfy": "all"
}
],
"behaviors": [],
"criteria": [],
"criteriaMustSatisfy": "all"
}
],
"behaviors": [
{
"name": "xxx",
"options": {}
}
],
"options": {
"is_secure": true
},
"variables": []
},
"warnings": [
],
"Format": "xxx"
}
我可能搞错了json结构,但是我现在的jq查询如下:
(.rules.children[].children[] | select(.name | contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")| not ))
这有效,除了 return json 从 .rules.children[].children[]
中排除子项目。
如何让 jq return 整个 json 文件排除过滤器中识别的 json?
del/1
可以根据路径表达式删除节点
这个例子似乎不是最小的,所以让我们考虑一下:
{"a":{"c":[
{"d":{"c":[{"e":"xyzzy"},{"e":2}]}},
{"d":{"c":[{"e":"xyzzy"},{"e":2}]}} ]}}
现在假设我们要删除 .e == "xyzz"
:
del( .a.c[].d.c[] | select(.e == "xyzzy") )
这将导致: {"a":{"c":[{"d":{"c":[{"e":2}]}},{"d": {"c":[{"e":2}]}}]}}
很遗憾,jq 1.5不支持del/1
中的复杂路径规范;然而,使用足够新的 jq 版本,我们可以写:
del( .a.c[].d.c[] | select(.e | type == "string" and contains("xyzzy") ) )
因此,对于 jq 1.5 的 above-mentioned 警告,您可以这样写:
del(.rules.children[].children[] | select(.name| contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")))
jq 1.5 的解决方法
.rules.children[].children |=
map(select((.name? // "")
| contains("7004389c-c47a-4611-9bd7-9f5dfe051d17")
| not))