Search code examples
jsonsumjqupdates

How to sum values in json using jq


I just started using jq parser as i need to parse some values out of a json file and make few changes and output an updated json file with the changes. Here is one of the samples out of many i'm working on.

input json:

{
  "name": ".",
  "metadata": {
    "path": ".",
    "type": "terraform_dir",
    "terraformWorkspace": "default"
  },
  "pastBreakdown": {
    "resources": [],
    "totalHourlyCost": "0",
    "totalMonthlyCost": "0"
  },
  "breakdown": {
    "resources": [
      {
        "name": "vm01",
        "metadata": {},
        "hourlyCost": "0.007989726027400584",
        "monthlyCost": 3.9660999999999986,
        "costComponents": [
          {
            "name": "vm01-201",
            "unit": "years",
            "hourlyQuantity": "0.0001141552511416",
            "monthlyQuantity": "0.0833333333333333",
            "price": "69.99",
            "hourlyCost": "0.007989726027400584",
            "monthlyCost": "5.832499999999997667"
          }
        ]
      },
      {
        "name": "public_ip.example",
        "metadata": {},
        "hourlyCost": "0.005",
        "monthlyCost": 2.482,
        "costComponents": [
          {
            "name": "IP address (static)",
            "unit": "hours",
            "hourlyQuantity": "1",
            "monthlyQuantity": "730",
            "price": "0.005",
            "hourlyCost": "0.005",
            "monthlyCost": "3.65"
          }
        ]
      },
      {
        "name": "storage_account",
        "metadata": {},
        "hourlyCost": "0.17575342465753424425",
        "monthlyCost": 87.24400000000001,
        "costComponents": [
          {
            "name": "Write",
            "unit": "10K operations",
            "hourlyQuantity": "0.136986301369863",
            "monthlyQuantity": "100",
            "price": "0.1",
            "hourlyCost": "0.0136986301369863",
            "monthlyCost": "10"
          },
          {
            "name": "List",
            "unit": "10K operations",
            "hourlyQuantity": "0.136986301369863",
            "monthlyQuantity": "100",
            "price": "0.05",
            "hourlyCost": "0.00684931506849315",
            "monthlyCost": "5"
          },
          {
            "name": "Read",
            "unit": "10K operations",
            "hourlyQuantity": "0.0136986301369863",
            "monthlyQuantity": "10",
            "price": "0.01",
            "hourlyCost": "0.000136986301369863",
            "monthlyCost": "0.1"
          },
          {
            "name": "All other operations",
            "unit": "10K operations",
            "hourlyQuantity": "0.136986301369863",
            "monthlyQuantity": "100",
            "price": "0.004",
            "hourlyCost": "0.000547945205479452",
            "monthlyCost": "0.4"
          },
          {
            "name": "retrieval",
            "unit": "GB",
            "hourlyQuantity": "1.3698630136986301",
            "monthlyQuantity": "1000",
            "price": "0.01",
            "hourlyCost": "0.013698630136986301",
            "monthlyCost": "10"
          },
          {
            "name": "write",
            "unit": "GB",
            "hourlyQuantity": "1.3698630136986301",
            "monthlyQuantity": "1000",
            "price": "0.0025",
            "hourlyCost": "0.00342465753424657525",
            "monthlyCost": "2.5"
          },
          {
            "name": "index",
            "unit": "10K tags",
            "hourlyQuantity": "0.0136986301369863",
            "monthlyQuantity": "10",
            "price": "0.03",
            "hourlyCost": "0.000410958904109589",
            "monthlyCost": "0.3"
          }
        ]
      }
    ],
    "totalMonthlyCost": "sum value"

From the above json i need to sum the monthlyCost of each resources and update total value in totalMonthlyCost

So the input would be "3.9660999999999986 + 2.482 + 87.24400000000001" the sum of these values should be updated in totalMonthlyCost

I have been trying various options but no luck. I could calculate the values within the array but not sure how to update the value in totalMonthlyCost


Solution

  • In two steps in accordance with the task description:

    (.breakdown.resources | map(.monthlyCost) | add) as $sum
    | .breakdown.totalMonthlyCost = $sum
    

    This can be written without the intermediate variable:

    .breakdown.totalMonthlyCost 
     = (.breakdown.resources | map(.monthlyCost) | add)
    

    or more DRYly:

    .breakdown
     |= (.totalMonthlyCost = (.resources | map(.monthlyCost) | add))