Reputation: 27
I have json:
"spec": {
"background": true,
"failurePolicy": "Fail",
"rules": [
{
"exclude": {
"resources": {}
},
"generate": {
"clone": {}
},
"match": {
"resources": {
"kinds": [
"networking.k8s.io/v1/NetworkPolicy"
]
}
},
"mutate": {},
"name": "validate-nodeport",
"validate": {
"message": "Services of type NodePort are not allowed.",
"pattern": {
"spec": {
"type": "!NodePort"
}
}
}
}
],
"validationFailureAction": "audit"
},
"status": {
"ready": true
}
}
I have jq command:
(.spec.rules[0].match.resources.kinds[] / "/")
| [select(.[1])[0] // null, select(.[2])[1] // null, last]
as [$version,$group,$kind]
| {$version,$group,$kind}
But sometimes field "version" or "group" maybe empty. I need to write with the following condition - if the string is null, then it is not necessary to write it.
Upvotes: 0
Views: 940
Reputation: 36646
The {$version,$group,$kind}
part from my other answer was included to show how to make use of the variables you requested to be created. Thus, if you don't want it to be written, don't generate it in the first place only to modify it later with with_entries(select(.value))
or the like. Instead, generate it differently, according to your needs.
For instance, instead of unconditionally using all three parts as in {$version,$group,$kind}
you may pick just the ones that are not null using [{$version},{$group},{$kind} | select(.[])] | add
: (Demo)
(.spec.rules[0].match.resources.kinds / "/")
| [select(.[1])[0] // null, select(.[2])[1] // null, last]
as [$version,$group,$kind]
| [{$version},{$group},{$kind} | select(.[])] | add
Better yet, modify the [...] as {...}
part directly to generate what you need, for instance: (Demo)
(.spec.rules[0].match.resources.kinds[] / "/")
| ({version:select(.[1])[0]} // {})
+ ({group:select(.[2])[1]} // {})
+ {kind: last}
Upvotes: 0
Reputation: 2325
Use select
filter:
jq '(.spec.rules[0].match.resources.kinds[] / "/")
| [select(.[1])[0] // null, select(.[2])[1] // null, last]
as [$version,$group,$kind]
| {$version,$group,$kind}
| select(.version != "")
| select(.group != "")
' \
spec.json
Or if you want to only reduce output:
jq '(.spec.rules[0].match.resources.kinds[] / "/")
| [select(.[1])[0] // null, select(.[2])[1] // null, last]
as [$version,$group,$kind]
| {$version,$group,$kind}
| if .version != "" then
if .group != "" then
{$version,$group,$kind}
else
{$version,$kind}
end
else
if .group != "" then
{$group,$kind}
else
{$kind}
end
end
' \
spec.json
Upvotes: 0
Reputation: 85895
The filter you have is already a pretty efficient way to deal with formation of objects, when all the individual fields (version, group and kind) are present and not required to re-write the whole thing to deal with one specific case.
To skip the null fields, just pipe your previous filter to below
with_entries(select(.value!=null))
i.e. the whole filter being below. See jqplay demo
(.spec.rules[0].match.resources.kinds[] / "/")
| [select(.[1])[0] // null, select(.[2])[1] // null, last]
as [$version,$group,$kind]
| {$version,$group,$kind}
| with_entries(select(.value!=null))
Upvotes: 2