prem
prem

Reputation: 31

Combine multiple json to single json using jq

I am new to jq and stuck with this problem for a while. Any help is appreciable.

I have two json files,

In file1.json:

{
    "version": 4,
    "group1": [
        {
            "name":"olditem1",
            "content": "old content"
        }
    ],
    "group2": [
        {
            "name":"olditem2"
        }
    ]
}

And in file2.json:

{
    "group1": [
        {
            "name" : "newitem1"
        },
        {
            "name":"olditem1",
            "content": "new content"
        }
    ],
    "group2": [
        {
            "name" : "newitem2"
        }
    ]
}

Expected result is:

{
    "version": 4,
    "group1": [
        {
            "name":"olditem1",
            "content": "old content"
        },
        {
            "name" : "newitem1"
        }
    ],
    "group2": [
        {
            "name":"olditem2"
        },
        {
            "name" : "newitem2"
        }
    ]
}

Criterial for merge:

  1. Has to merge only group1 and group2
  2. Match only by name

I have tried

jq -S '.group1+=.group1|.group1|unique_by(.name)' file1.json file2.json

but this is filtering group1 and all other info are lost.

Upvotes: 1

Views: 1030

Answers (1)

pmf
pmf

Reputation: 36088

This approach uses INDEX to create a dictionary of unique elements based on their .name field, reduce to iterate over the group fields to be considered, and an initial state created by combining the slurped (-s) input files using add after removing the group fileds to be processed separately using del.

jq -s '
  [ "group1", "group2" ] as $gs | . as $in | reduce $gs[] as $g (
    map(del(.[$gs[]])) | add; .[$g] = [INDEX($in[][$g][]; .name)[]]
  )
' file1.json file2.json
{
  "version": 4,
  "group1": [
    {
      "name": "olditem1",
      "content": "new content"
    },
    {
      "name": "newitem1"
    }
  ],
  "group2": [
    {
      "name": "olditem2"
    },
    {
      "name": "newitem2"
    }
  ]
}

Demo

Upvotes: 2

Related Questions