Comment puis-je arrondir le chiffre de la dernière colonne à 2 décimales après un point en utilisant JQ?

Comment arrondir le chiffre de la dernière colonne à 2 décimales?

J’ai json:

{ "took": 1, "timed_out": false, "_shards": { "total": 9, "successful": 9, "failed": 0 }, "hits": { "total": 2, "max_score": 2.575364, "hits": [ { "_index": "my-2017-08", "_type": "log", "_id": "AV5V8l0oDDWj-VP3YnCw", "_score": 2.575364, "_source": { "acb": { "version": 1, "id": "7", "owner": "pc", "item": { "name": "Account Average Latency", "short_name": "Generate", "description": "Generate of last month" }, "service": "gsm" }, "@timestamp": "2017-07-31T22:00:00.000Z", "value": 210.08691986891395 } }, { "_index": "my-2017-08", "_type": "log", "_id": "AV5V8lbE28ShqBNuBl60", "_score": 2.575364, "_source": { "acb": { "version": 1, "id": "5", "owner": "pc", "item": { "name": "Profile Average Latency", "short_name": "Profile", "description": "Profile average latency of last month" }, "service": "gsm" }, "@timestamp": "2017-07-31T22:00:00.000Z", "value": 370.20963260148716 } } ] } } 

J’utilise JQ pour obtenir des données csv:

 ["Name","Description","Result"],(.hits.hits[]._source | [.acb.item.name,.acb.item.description,.value])|@csv 

Je vois le résultat:

 "Name","Description","Result" "Account Average Latency","Generate of last month",210.08691986891395 "Profile Average Latency","Profile average latency of last month",370.20963260148716 

J’ai 210.08691986891395 et 370.20963260148716 mais je veux 210.09 et 370.21

Je le passerais à awk via pipeline:

 jq -r '["Name","Description","Result"],(.hits.hits[]._source | [.acb.item.name,.acb.item.description,.value])|@csv' yourfile | awk 'BEGIN{ FS=OFS="," }NR>1{ $3=sprintf("%.2f",$3) }1' 

Le résultat:

 "Name","Description","Result" "Account Average Latency","Generate of last month",210.09 "Profile Average Latency","Profile average latency of last month",370.21 

Selon votre version de jq, vous pouvez avoir access à certaines fonctions mathématiques de cstdlib (par exemple, sin ou cos ). Puisque vous êtes sur * nix, il est fort probable que vous le fassiez. Dans ma version particulière, je ne semble pas avoir access à la round mais peut-être que vous le faites.

 def roundit: .*100.0|round/100.0; ["Name","Description","Result"], (.hits.hits[]._source | [.acb.item.name, .acb.item.description, (.value|roundit)]) | @csv 

Heureusement, il pourrait être mis en œuvre en termes de floor auquel j’ai access.

 def roundit: .*100.0 + 0.5|floor/100.0; 

Voici votre filtre actuel avec un reformatage mineur:

  ["Name", "Description", "Result"] , ( .hits.hits[]._source | [.acb.item.name, .acb.item.description, .value] ) | @csv 

Voici un filtre qui arrondit la colonne de valeur. Notez que nous le faisons après le @csv afin que nous ayons un contrôle total sur la chaîne

 def round: # eg (split(".") + ["0"])[:2] # ["210","08691986891395"] | "\(.[1])000"[:3] as $x | [.[0], $x[:2], $x[2:3]] # ["210","08","6"] | map(tonumber) # [210,8,6] | if .[2] > 4 then .[2] = 0 | .[1] += 1 else . end # [210,9,0] | if .[1] > 99 then .[1] = 0 | .[0] += 1 else . end # [210,9,0] | ["\(.[0])", "00\(.[1])"[-2:]] # ["210","09"] | join(".") # 210.09 ; ( ["Name", "Description", "Result"] | @csv ) , ( .hits.hits[]._source | [.acb.item.name, .acb.item.description, .value] | @csv | split(",") | .[-1] |= round | join(",") ) 

Si ce filtre est dans filter.jq et que les données exemple se data.json dans data.json alors la commande

 $ jq -Mr -f filter.jq data.json 

produit

 "Name","Description","Result" "Account Average Latency","Generate of last month",210.09 "Profile Average Latency","Profile average latency of last month",370.21