Home > other >  jq: populate template json
jq: populate template json

Time:11-11

I'd like to populate a json-data.json json data objects using a json-template.json.

Example:

json-data.json:

[
  {name: "John", familyName: "Smith"},
  {name: "Samuel", familyName: "Schnaider"}
]

And my json-template.json:

{
  key1: "value1",
  key2: "value2",
  name: "XXX",
  familyName: "YYY"
}

My desired result would be:

[
  {
    key1: "value1",
    key2: "value2",
    name: "John",
    familyName: "Smith"
  },
  {
    key1: "value1",
    key2: "value2",
    name: "Samuel",
    familyName: "Schnaider"    
  }
]

Any ideas about how to get it using jq?

CodePudding user response:

To keep things simple, since you indicated the intent is that json-data.json contain JSON, let's suppose that it contains valid JSON.

It would probably be simpler also if the template were valid JSON, but in case you're stuck with templates like the one you showed, let's go with that.

Since the template shown is not valid JSON but is valid as a jq object specification, let's start by supposing we can make it part of a jq program, e.g. by

def template:
{
  key1: "value1",
  key2: "value2",
  name: "XXX",
  familyName: "YYY"
}
;

We have now only to write a filter for converting an input object to the form specified by the template:

def fillin($template):
  . as $in
  | reduce ($template|keys_unsorted[]) as $k ($template; if $in|has($k) then .[$k] = $in[$k] else . end);

With your input, we have then only to call:

map(fillin(template))

Putting all the jq code in a single file, the invocation would then look like this:

jq -f populate-template.jq json-data.json

CodePudding user response:

If the template is potentially invalid as JSON and if you want to keep it in a separate file, then, assuming a bash or bash-like shell, you could write:

< json-data.json jq --argfile t <(jq -n -f template.txt) '

  def fillin($template):
    . as $in
    | reduce ($template|keys_unsorted[]) as $k ($template; if $in|has($k) then .[$k] = $in[$k] else . end);

  map(fillin($t))
' 
  • Related