This is a kind of extension to my previous question JQ - Deep child value replace through wildcard search and merge to the original JSON
I want to check the presence of a particular key in some parents before replacing the child. Loosely, translated to CSS selector, I want something like * > fixedKeyCheckPresence > * > fixedKeyCheckValue
Input:
{
"randomKey1": {
"randomKey2": [
{
"randomKeyUnderAnyLevel11": {
"fixedKeyCheckPresence": {
"randomeKeyUnderAnyLevel23": {
"fixedKeyCheckValue": "Foo"
}
}
}
}
]
},
"randomKey11": {
"fixedKeyCheckPresence": {
"randomeKeyUnderAnyLevel123": {
"fixedKeyCheckValue": "Foo"
}
}
}
}
Expected Output:
{
"randomKey1": {
"randomKey2": [
{
"randomKeyUnderAnyLevel11": {
"fixedKeyCheckPresence": {
"randomeKeyUnderAnyLevel23": {
"fixedKeyCheckValue": "Bar"
}
}
}
}
]
},
"randomKey11": {
"fixedKeyCheckPresence": {
"randomeKeyUnderAnyLevel123": {
"fixedKeyCheckValue": "Bar"
}
}
}
}
Tried: (.. | select(try has("fixedKeyCheckPresence")) | .fixedKeyCheckValue) |= (sub("^Foo$";"Bar"))
jq play: https://jqplay.org/s/_YlLSyTEc7
CodePudding user response:
You can combine walk
with ..
:
jq 'walk(
(.fixedKeyCheckPresence? | .. |
select(has("fixedKeyCheckValue")?).fixedKeyCheckValue) |= sub("^Foo$";"Bar")
)' input.json
.fixedKeyCheckPresence?
takes care of find the object key fixedKeyCheckPresence
and leaves everything else intact.
Then under .fixedKeyCheckPresence
, we enumerate all sub-nodes with ..
and select the object containing fixedKeyCheckValue
.