2017-09-08 107 views
0

我如何将最后一列的数字舍入到小数点后两位?如何将最后一列的数字舍入到使用JQ的小数点后两位小数?

我有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 
     } 
     } 
    ] 
    } 
} 

我用JQ获得CSV数据:

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

我看到的结果:

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

210.08691986891395370.20963260148716但我想要210.09370.21

回答

0

我将通过管道把它传递给AWK

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' 

输出:

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

根据您的JQ的身材,你可能可以访问一些cstdlib math functions(例如,sincos)。既然你在* nix上,你很可能会这样做。在我的特定版本中,我似乎无法访问round,但也许你会这样做。

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

幸运的是,它可以按照我有权访问的floor来实现。

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

感谢您的回答。但我检查了这一点,我看到一个错误: jq:错误:round/0未定义在,第1行: def roundit:。* 100.0 | round/100.0; [“名称”,“描述”,“结果”],(.hits.hits [] ._ source | [.acb.item.name,.acb.item.description,.value | roundit])| @csv jq:1编译错误 是的,我正在使用Linux(jq版本1.5) –

+0

是的,似乎'round'也不适合你。但我们也可以用'floor'来实现。不完全一样,但会足够接近。 –

0

这里是您当前的过滤器,简单的重新格式化:

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

这里是一个过滤器,其舍入值列。请注意,我们做到这一点,@csv后,使我们有超过字符串完全控制

def round:            # e.g. 
    (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(",") 
) 

如果该过滤器是filter.jq和样本数据是data.json则命令

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

产生

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