2017-09-08 69 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 
相關問題