clay
clay

Reputation: 20370

jq JSON handle missing fields

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

Answers (3)

clay
clay

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

peak
peak

Reputation: 116670

There are several possible approaches, each with variants. Here are illustrations of a constructive approach, and a postprocessing one.

Constructive

{a} + ((select(has("b")) | {"b2": .b | fromjson}) // {}) + {c}

or more concisely but with slightly different semantics:

[{a}, (select(.b) | {b2: .b | fromjson}), {c}] | add

Postprocessing

{a, "b2": (.b | fromjson? // null), c}
| if .b2 == null then del(.b2) else . end

Upvotes: 5

Inian
Inian

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

Related Questions