GustavMahler
GustavMahler

Reputation: 687

jq merge two json files and create a key as the filename for each in merged file

Question:

How do you merge multiple JSON files using jq. Each of the merged objects must have their own key name in the final merged file.

file1.json :

{
  "shoe": 0,
  "temp": "10"
}

file2.json:

{
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}

Desired merged output:

{
  "file1": {
    "shoe": 0,
    "temp": "10"
  },
  "file2": {
    "num": {
      "sock": 0,
      "ratio": {
        "cat": 100,
        "dog": 0
      }
    },
    "hair": "blue"
  }
}

Attempt 1: The issue with the below is that the objects hierarchy is merged if that makes sense:

jq --slurp 'add' file1.json file2.json

Attempt 1 Output (not what I want):

{
  "shoe": 0,
  "temp": "10"
  "num": {
    "sock": 0,
    "ratio": {
      "cat": 100,
      "dog": 0
    }
  },
  "hair": "blue"
}

Upvotes: 5

Views: 1959

Answers (1)

Inian
Inian

Reputation: 85790

jq has a built-in variable input_filename that represents the filename the filter is being applied on. So you can do something like

jq -n 'reduce inputs as $s (.; .[input_filename] += $s)'  file1.json file2.json

The reduce expression takes the entire input objects and constructs the final JSON with the key as the filename being used.

You can go one level further and want to optionally remove the extension part of the JSON .json, use the trimming functions available. The below code assumes the input file is ending with .json and won’t work with any other extensions

jq -n 'reduce inputs as $s (.; (.[input_filename|rtrimstr(".json")]) += $s)'

Upvotes: 10

Related Questions