I have the following json input:
{
"to_exclude": {
"x": "something",
"aa": {
"x": "something",
"aaa": {
"x": "something"
}
}
},
"a": {
"x": "something else",
"aa": {
"x": "something else",
"aaa": {
"x": "something else"
}
}
},
"b": {
"x": "something else",
"bb": {
"x": "something else",
"bbb": {
"x": "something else"
}
}
},
"...": {
"x": "something else",
"......": {
"x": "something else",
".........": {
"x": "something else"
}
}
}
}
I'd like to replace the values of all x
keys that are not descendants of to_exclude
by anything
.
The output should look like this:
{
"to_exclude": {
"x": "something",
"aa": {
"x": "something",
"aaa": {
"x": "something"
}
}
},
"a": {
"x": "anything",
"aa": {
"x": "anything",
"aaa": {
"x": "anything"
}
}
},
"b": {
"x": "anything",
"bb": {
"x": "anything",
"bbb": {
"x": "anything"
}
}
},
"...": {
"x": "anything",
"......": {
"x": "anything",
".........": {
"x": "anything"
}
}
}
}
How can I achieve this in a similarily compact way as I could easily achieve the opposite? (the replacement for all values of x
keys that are descendants of to_exclude
):
.to_exclude |= (.. |= ( if type == "object" and has("x") then .x = "anything" else . end))
Output:
{
"to_exclude": {
"x": "anything",
"aa": {
"x": "anything",
"aaa": {
"x": "anything"
}
}
},
"a": {
"x": "something else",
"aa": {
"x": "something else",
"aaa": {
"x": "something else"
}
}
},
"b": {
"x": "something else",
"bb": {
"x": "something else",
"bbb": {
"x": "something else"
}
}
},
"...": {
"x": "something else",
"......": {
"x": "something else",
".........": {
"x": "something else"
}
}
}
}
Instead of applying a function to .to_exclude
using .to_exclude |= …
, apply it to all keys after filtering them using a simple select
. For example:
.[keys[] | select(. != "to_exclude")] |= …
To exclude a list of keys, you could also use array subtraction:
.[keys - ["to_exclude"] | .[]] |= …