Reputation: 20370
Normally, I want to do something like this, which works:
echo '{"a": 123, "b": "{\"embedded\": 456}", "c": 789}' | jq '{a, "b2": .b | fromjson, c}'
that works and yields:
{
"a": 123,
"b2": {
"embedded": 456
},
"c": 789
}
Sometimes, field "b" is missing and in that case the above jq will error:
echo '{"a": 123, "c": 789}' | jq '{a, "b2": .b | fromjson, c}'
That gives a null error, which makes sense because b is missing so .b
is null and fromjson
errors on null. I want to write my jq
command so if b
is missing for a record, then it isn't output. I want to simply get this:
{
"a": 123,
"c": 789
}
I've skimmed through the jq
Reference manual. I'm having trouble getting the if/else/end construct to solve this. I don't see any other null handling functions or language constructs available.
Upvotes: 7
Views: 3778
Reputation: 20370
This works the best, combining suggestions from peak and Inian's answers:
# example with b
echo '{"a": 123, "b": "{\"embedded\": 456}", "c": 789}' | jq '{a, c} + if has("b") then {"b": .b | fromjson} else {} end'
# example without b
echo '{"a": 123, "not_b": "{\"embedded\": 456}", "c": 789}' | jq '{a, c} + if has("b") then {"b": .b | fromjson} else {} end'
Upvotes: 0
Reputation: 116670
There are several possible approaches, each with variants. Here are illustrations of a constructive approach, and a postprocessing one.
{a} + ((select(has("b")) | {"b2": .b | fromjson}) // {}) + {c}
or more concisely but with slightly different semantics:
[{a}, (select(.b) | {b2: .b | fromjson}), {c}] | add
{a, "b2": (.b | fromjson? // null), c}
| if .b2 == null then del(.b2) else . end
Upvotes: 5
Reputation: 85550
You need something like below. Use the if condition to check against the presence of .b
to be null
. Form the structure to have all fields when not null.
jq 'if .b != null then { a, "b2":(.b|fromjson), c } else {a, c} end'
Upvotes: 3