HectorOfTroy407
HectorOfTroy407

Reputation: 1907

JQ create field only if it exists

In jq, how do I ensure a k,v is only created if it exists in the object being inspected? For example, let's say I have an object like:

{
 "student":{
    "name": "george",
    "age" : "15",
    "quote": "Hello I am George"
    }
 }

And I do cat text.txt | jq '{name: .student.name, quote: .student.quote}' to create:

  {
   "name": "george",
   "quote": "Hello I am George"
   }

However, some of the entries are incomplete, and I don't want to write an empty K,V. Let's say I get:

{
 "student":{
    "name": "Shirley"
  }
} 

With the current jq above this would create:

 {
  "name": "Shirley",
  "quote": null,
  }

Is there a way I can tell jq to only create the 'quote' key if it exists (i.e. is not null)? Or more generally, create ALL keys only if they exist in the object being inspected.

Upvotes: 3

Views: 7398

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134491

If you know what the keys are ahead of time and they're straight properties, just build up an array of the keys you want and check if the object contains those keys.

$ jq --argjson keys '["name","quote"]' '
def copy_keys($keys): . as $o
    | reduce $keys[] as $k ({}; if ($o|has($k)) then .[$k] = $o[$k] else . end)
    ;
.student | copy_keys($keys)' text.txt

But the way you worded your question, "Or more generally, create ALL fields only if they exist in the object being inspected," you just want all the keys in the object as long as it has a key. Why not just get the object?

$ jq '.student' text.txt

Upvotes: 2

peak
peak

Reputation: 116870

This is where object addition comes in very handy, especially since $obj + null yields $obj (if $obj is a JSON object):

.student |  {name} + if has("quote") then {quote} else null end

or equivalently:

def maybe(k): if has(k) then {(k): .[k]} else null end;
.student |  {name} + maybe("quote")

A slightly different approach, with subtly different semantics, would be:

.student |  {name} + ((select(.quote) | {quote}) // null)

Of course other variations are possible.

Upvotes: 9

Related Questions