How to combine JSON objects with the same key, using jq

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?

Asked By: Stephanie Lage

||

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.

Answered By: Kusalananda
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.