Reputation: 63
I have jsonlines data which and would like to find 1. value is empty object or 2. key is not exist . In the following sample, I wonder take the result of items which .items.spec.resource={} or .items.spec.limits|requests which key not exist.
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
Here comes the result
{
"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": {}
}
]
}
}
I don't understand the repeat part, I guess it is because of the conditions, how can I get the part of above conditions, I would like to filter the part of metadata and spec.containers which meet conditions.
Upvotes: 4
Views: 3591
Reputation: 116870
In accordance with your explanatory comment, it would appear you could achieve what you want using jq "$-variables":
jq -c '
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources.requests == null or
.resources.limits == null or
.resources == {})
| [$podname, .name]
'
With your data, the output produced by the above would be:
["pod02","con02_02"]
["pod03","con03_02"]
The test for the third condition (.resources == {}) is actually redundant, so the above jq filter is equivalent to:
.items[]
| .metadata.name as $podname
| .spec.containers[]
| select(.resources | (.requests == null or .limits == null ))
| [$podname, .name]
To check for the existence of a key, it is generally appropriate to use has/1
since {} | .key
evaluates to null
. Thus you might wish to replace the select()
above with:
select( any(.resources | has("requests", "limits"); not) )
Upvotes: 4