具有目标值或键的对象的 jq 过滤器不存在
jq filter for object with target value or key is not exist
我有 jsonlines 数据,想找到 1.value is empty object 或 2.key is not exist。在下面的示例中,我想知道 .items.spec.resource={} 或 .items.spec.limits| 请求哪个键不存在的项目的结果。
data='{"items":[{"metadata":{"name":"pod01"},"spec":{"containers":[{"name":"con01_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con01_02","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod02"},"spec":{"containers":[{"name":"con02_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con02_02","resources":{"limits":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod03"},"spec":{"containers":[{"name":"con03_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con03_02","resources":{}}]}}]}'
list=$(echo $data | jq '.items[] | select(.spec.containers[].resources.requests == null or .spec.containers[].resources.limits == null or .spec.containers[].resources == {})')
echo $list
结果出来了
{
"metadata": { "name": "pod02" },
"spec": {
"containers": [
{ "name": "con02_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con02_02",
"resources": {
"limits": { "cpu": "100m" }
}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{
"name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{ "name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{ "name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
repeat部分看不懂,估计是条件的问题,如何获取以上条件的部分,我想过滤metadata和spec.containers满足的部分条件。
根据您的解释性评论,您似乎可以使用 jq "$-variables" 实现您想要的:
jq -c '
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources.requests == null or
.resources.limits == null or
.resources == {})
| [$podname, .name]
'
根据您的数据,上面产生的输出将是:
["pod02","con02_02"]
["pod03","con03_02"]
简化
第三个条件(.resources == {})的测试其实是多余的,所以上面的jq filter相当于:
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources | (.requests == null or .limits == null ))
| [$podname, .name]
存在密钥
要检查密钥是否存在,通常使用 has/1
是合适的,因为 {} | .key
的计算结果为 null
。因此,您可能希望将上面的 select()
替换为:
select( any(.resources | has("requests", "limits"); not) )
我有 jsonlines 数据,想找到 1.value is empty object 或 2.key is not exist。在下面的示例中,我想知道 .items.spec.resource={} 或 .items.spec.limits| 请求哪个键不存在的项目的结果。
data='{"items":[{"metadata":{"name":"pod01"},"spec":{"containers":[{"name":"con01_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con01_02","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod02"},"spec":{"containers":[{"name":"con02_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con02_02","resources":{"limits":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod03"},"spec":{"containers":[{"name":"con03_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con03_02","resources":{}}]}}]}'
list=$(echo $data | jq '.items[] | select(.spec.containers[].resources.requests == null or .spec.containers[].resources.limits == null or .spec.containers[].resources == {})')
echo $list
结果出来了
{
"metadata": { "name": "pod02" },
"spec": {
"containers": [
{ "name": "con02_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con02_02",
"resources": {
"limits": { "cpu": "100m" }
}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{
"name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{ "name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
{
"metadata": { "name": "pod03" },
"spec": {
"containers": [
{ "name": "con03_01",
"resources": {
"limits": { "cpu": "100m" },
"requests": { "cpu": "100m" }
}
},
{ "name": "con03_02",
"resources": {}
}
]
}
}
repeat部分看不懂,估计是条件的问题,如何获取以上条件的部分,我想过滤metadata和spec.containers满足的部分条件。
根据您的解释性评论,您似乎可以使用 jq "$-variables" 实现您想要的:
jq -c '
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources.requests == null or
.resources.limits == null or
.resources == {})
| [$podname, .name]
'
根据您的数据,上面产生的输出将是:
["pod02","con02_02"]
["pod03","con03_02"]
简化
第三个条件(.resources == {})的测试其实是多余的,所以上面的jq filter相当于:
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources | (.requests == null or .limits == null ))
| [$podname, .name]
存在密钥
要检查密钥是否存在,通常使用 has/1
是合适的,因为 {} | .key
的计算结果为 null
。因此,您可能希望将上面的 select()
替换为:
select( any(.resources | has("requests", "limits"); not) )