Will
Will

Reputation: 2410

Perform average of values of a particular field inside a JSON using jq

I have the following JSON data.

{
   "meta":{
      "earliest_ts":1601425980,
      "latest_ts":1601482740,
      "interval":"minutes",
      "level":"cluster",
      "entity_id":"xxxxx-xxxxx-xxxxx-xxxxx-xxxxx",
      "stat_labels":[
         "status_code_classes_per_workspace_total"
      ],
      "entity_type":"workspace",
      "start_ts":"1601425980"
   },
   "stats":{
      "cluster":{
         "1601431620":{
            "3xx":2,
            "4xx":87,
            "5xx":31,
            "2xx":352
         },
         "1601472780":{
            "3xx":14,
            "4xx":296,
            "5xx":2,
            "2xx":3811
         },
         "1601479140":{
            "3xx":17,
            "4xx":397,
            "5xx":19,
            "2xx":4399
         }
      }
   }
}

I try to do the average of all the "3xx" fields.

Using jq, I manage to get the key for each of my cluster :

echo $data | jq -r '.stats.cluster|keys' | while read key; do 
  echo $key
done

Output :

[
"1601431620",
"1601472780",
"1601479140"
]

But when I try to go further I can't manage to further and to retrieve the data from each field. I got some insperation from this.

The code below doesn't work, but you get the idea :

 # total var will be used to calculate the average
 total=$(echo $data | jq ".stats.cluster" | jq length)

 # for each cluster ...
 echo $data | jq '.stats.cluster|keys' | while read key; do
    # ... we retrieve the value "3xx"
    i=$($data | jq '.stats.cluster.$key."3xx"')
    # ... that we add into a sum var
    sum=$(( sum + i ))
 done
 
 # we calculate the average
 avg=$(( $sum / $total ))
 echo "The average is $avg"

I can't path directly to the data in jq like jq '.stats.cluster."1601431620"."3xx" because the cluster are so many and change all the time.

The desired output with my example above would be 11 as (2 + 14 + 17) / 3, those number all coming from the 3xx's items field.

Upvotes: 2

Views: 913

Answers (1)

Benjamin W.
Benjamin W.

Reputation: 52431

You can get the value directly from jq:

$ jq '[.stats.cluster[]["3xx"]] | add / length' <<< "$data"
11

Upvotes: 5

Related Questions