sum values in 2 JSON objects from 2 files

Viewed 349

I am using jq tools to merge 2 json files but there are some duplicate keys, and I would like for the duplicate keys to sum their values.

Here are the files:

file1:

{
  "total": {
    "seconds": 1490
  },
  "days": {
    "2020-05-20": {
      "seconds": 1400
    },
    "2020-05-19": {
      "seconds": 30
    },
    "2020-05-18": {
      "seconds": 60
    }
  }
}

file2:

{
  "total": {
    "seconds": 295
  },
  "days": {
    "2020-05-22": {
      "seconds": 120
    },
    "2020-05-21": {
      "seconds": 80
    },
    "2020-05-20": {
      "seconds": 95
    }
  }
}

Expected output:

{
  "total": {
    "seconds": 1785
  },
  "days": {
    "2020-05-22": {
      "seconds": 120
    },
    "2020-05-21": {
      "seconds": 80
    },
    "2020-05-20": {
      "seconds": 1495
    },
    "2020-05-19": {
      "seconds": 30
    },
    "2020-05-18": {
      "seconds": 60
    }
  }
}

I have tried starting with this command, but do not know where to go next:

jq -s '.[0] * .[1]' file1 file2
2 Answers

Below program works fine for your samples, but it won't work if the objects in your actual inputs have other keys with non-number values.

jq '. as $in |
reduce paths(numbers) as $p (input;
  setpath($p; getpath($p) + ($in | getpath($p))
)' file1 file2

Online demo

jq -s '
    reduce (paths(numbers) as $p | [$p[1:], getpath($p)]) as $i 
        ({}; setpath($i[0]; getpath($i[0]) + $i[1]))' file1 file2

This only considers leaf nodes which are numbers and produces a merged object with all numbers at similar paths summed up. It works for any number of files.

Online Demo. https://jqplay.org/s/DRkQwRC9Rx

Related