Reputation: 2515
I'm trying to prune nodes deeply within a JSON structure and I'm puzzled why empty
behaves seemingly different from a normal value here.
[
{
"name": "foo",
"children": [{
"name": "foo.0",
"color": "red"
}]
},
{
"name": "bar",
"children": [{
"name": "bar.0",
"color": "green"
},
{
"name": "bar.1"
}]
},
{
"name": "baz",
"children": [{
"name": "baz.0"
},
{
"name": "baz.1"
}]
}
]
jq '(.[].children|.[])|=if has("color") then . else empty end' foo.json
[
{
"name": "foo",
"children": [
{
"name": "foo.0",
"color": "red"
}
]
},
{
"name": "bar",
"children": [
{
"name": "bar.0",
"color": "green"
}
]
},
{
"name": "baz",
"children": [
{
"name": "baz.1"
}
]
}
]
The output I get, except without the baz.1
child, as that one doesn't have a color.
Apart from the right solution, I'm also curious why replacing empty
in the script by a regular value like 42
would replace the children without colors with 42 as expected, but when replacing with empty
, it looks like the else
branch doesn't get executed?
Upvotes: 0
Views: 96
Reputation: 43983
.[].children |= map(select(.color))
Will remove children
that does not has
an color
so the output becomes:
[
{
"name": "foo",
"children": [
{
"name": "foo.0",
"color": "red"
}
]
},
{
"name": "bar",
"children": [
{
"name": "bar.0",
"color": "green"
}
]
},
{
"name": "baz",
"children": []
}
]
Regarding why your filter does not seem to like empty
;
This git issue seems to be the cause, multiple elements with empty
will fail.
Upvotes: 1
Reputation: 50775
There must be a bug with assigning empty
to multiple paths.
In this case you can use del
instead:
del(.[].children[] | select(has("color") | not))
Upvotes: 1