当嵌套数组具有 key:value 匹配模式时如何忽略 json 元素?
How to ignore json elements when a nested array has an key:value matching patterm?
我一直在使用 jq(1) 并从 kubernetes api (api/v1/nodes) 得到类似的响应。
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z",
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
}
]
}
如您所见,数组中可以有很多项。有些带有 .spec.taints ,有些则没有。有些可能是空的,有些可能是满的。
我的目标是忽略所有有污点的项目"effect": "NoSchedule"
我发现这很麻烦,因为无论我尝试什么,我已经在线搜索了好几天,我都无法让它正常工作。
我已经走到这一步了,但现在卡住了
curl api | jq -c '.items[].spec.taints |= map(select(.effect | . != "NoSchedule"))'
如有任何帮助,我们将不胜感激。
我希望这会很有用,在这个例子中有 3 个项目,一个有效:NoSchedule,一个有效:anyother,一个有 taints empty。如果正确,你只需要第二个:
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
]
}
}
]
命令将是:
jq '.items[]|select(.spec.taints[].effect!="NoSchedule") ' data1.jtxt
结果:
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
}
注意:我把你的数据放在一个文件里模拟输入。
根据问题,我的理解是 taints
可以有多个条目。它可以是 NoSchedule
和其他值的混合。这是 jq
如果至少存在一个具有 effect
值 NoSchedule
的污点,则该项目将被忽略。
. as $in | $in * { items: $in.items | map(select(.spec.taints | all(.effect != "NoSchedule"))) }```
这会从 .items
数组中删除每个在 .spec.taints
中有一个数组的成员,而 .spec.taints
又至少有一个 .effect
设置为 "NoSchedule"
的对象项。在所有其他情况下,即只有 .effect
设置为其他对象的对象,或者 .taints
为空,或者根本没有 .taints
,或者根本没有 .spec
, 最多只有一个空对象 {}
作为 .items
数组的成员,该数组成员将被保留。
.items -= (.items | map(select(.spec.taints[].effect == "NoSchedule")?))
您可以使用 del
删除您想要的:
curl api | jq 'del(.items[] | select(.spec.taints[].effect == "NoSchedule")?)'
我一直在使用 jq(1) 并从 kubernetes api (api/v1/nodes) 得到类似的响应。
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z",
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
}
]
}
如您所见,数组中可以有很多项。有些带有 .spec.taints ,有些则没有。有些可能是空的,有些可能是满的。
我的目标是忽略所有有污点的项目"effect": "NoSchedule"
我发现这很麻烦,因为无论我尝试什么,我已经在线搜索了好几天,我都无法让它正常工作。
我已经走到这一步了,但现在卡住了
curl api | jq -c '.items[].spec.taints |= map(select(.effect | . != "NoSchedule"))'
如有任何帮助,我们将不胜感激。
我希望这会很有用,在这个例子中有 3 个项目,一个有效:NoSchedule,一个有效:anyother,一个有 taints empty。如果正确,你只需要第二个:
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
]
}
}
]
命令将是:
jq '.items[]|select(.spec.taints[].effect!="NoSchedule") ' data1.jtxt
结果:
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
}
注意:我把你的数据放在一个文件里模拟输入。
根据问题,我的理解是 taints
可以有多个条目。它可以是 NoSchedule
和其他值的混合。这是 jq
如果至少存在一个具有 effect
值 NoSchedule
的污点,则该项目将被忽略。
. as $in | $in * { items: $in.items | map(select(.spec.taints | all(.effect != "NoSchedule"))) }```
这会从 .items
数组中删除每个在 .spec.taints
中有一个数组的成员,而 .spec.taints
又至少有一个 .effect
设置为 "NoSchedule"
的对象项。在所有其他情况下,即只有 .effect
设置为其他对象的对象,或者 .taints
为空,或者根本没有 .taints
,或者根本没有 .spec
, 最多只有一个空对象 {}
作为 .items
数组的成员,该数组成员将被保留。
.items -= (.items | map(select(.spec.taints[].effect == "NoSchedule")?))
您可以使用 del
删除您想要的:
curl api | jq 'del(.items[] | select(.spec.taints[].effect == "NoSchedule")?)'