3

I have the following snippet exported as JSON:

{
  "daisy": {
    "dev": {
      "app_url": "example.com",
      "owner": "bob",
      "createat": "2022-06-17T15:31:58Z",
    }
  }
}
{
  "daisy": {
    "dev": {
      "appname": "daisy",
      "flavor": [
        "nodejs"
      ],
      "file": "manifests/daisy.yml"
    }
  }
}

I would like to combine these objects into something like this:

{
  "daisy": {
    "dev": {
      "app_url": "example.com",
      "owner": "bob",
      "createat": "2022-06-17T15:31:58Z",
      "appname": "daisy",
      "flavor": [
        "nodejs"
      ],
      "file": "manifests/daisy.yml"
    }
  }
}

How can I achieve this with jq?

1 Answer 1

12

Multiplying two objects together will merge them. The following uses reduce to successively build up a new object by merging the existing objects one by one.

Two similar ways to do this:

  1. Using -n and inputs with reduce:

    jq -n 'reduce inputs as $item ({}; . *= $item)' file
    

    This uses the inputs function, which returns the incoming objects one by one. This is combined with -n (--null-input) to disable the ordinary reading of inputs.

  2. Using -s and .[] with reduce:

    jq -s 'reduce .[] as $item ({}; . *= $item)' file
    

    This reads the original data with -s (--slurp) into an array, and reduce is used to iterate over that array. Note that this is severely memory-inefficient and slow if the input is huge.

The result, given your data (and correcting it by removing a comma on the createat line):

{
  "daisy": {
    "dev": {
      "app_url": "example.com",
      "owner": "bob",
      "createat": "2022-06-17T15:31:58Z",
      "appname": "daisy",
      "flavor": [
        "nodejs"
      ],
      "file": "manifests/daisy.yml"
    }
  }
}

Note that if two or more objects share the same key and if that key refers to a scalar or array, then the later objects in the input will overwrite the value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .