合并JSON文件并使用JQ重新计算百分比

时间:2016-12-30 02:49:33

标签: arrays json bash unix jq

我在bash shell脚本中使用jq每天处理一个JSON文件列表,将它们组合成一个新数组。在我将它们组合后,我需要根据数组中每个对象的值重新计算值。然后,这个新的JSON文件将在面向客户端的分析HTML报告中使用。

我非常接近它的工作,但无法弄清楚如何合并我的jq过滤器。

我可以在过滤器A 中创建一个重新计算的百分比数组,然后我可以在过滤器B 中输出我期望的数组(减去新的百分比值)但无法找到将这些组合成过滤器C 的方法。

JQ Playground网址: https://jqplay.org/#

JSON input (located on gist.github)

过滤A:

{"hits_percents": [(.[].hits.count / (group_by(.hits.count) | map(map(.hits.count))|add|add)*100)], "visitors_percents": [(.[].visitors.count / (group_by(.visitors.count) | map(map(.visitors.count))|add|add)*100)], "bytes_percents": [(.[].bytes.count / (group_by(.bytes.count) | map(map(.bytes.count))|add|add)*100)]}

输出A:

{
  "hits_percents": [
    1.2345679012345678,
    8.641975308641975,
    8.641975308641975,
    9.876543209876543,
    6.172839506172839,
    3.7037037037037033,
    1.2345679012345678,
    2.4691358024691357,
    58.0246913580247
  ],
  "visitors_percents": [
    4,
    28.000000000000004,
    28.000000000000004,
    8,
    4,
    8,
    4,
    8,
    8
  ],
  "bytes_percents": [
    0.31110007608374707,
    36.59886623706793,
    31.692110521802018,
    7.187835244744665,
    1.6285539319606,
    5.880482040688714,
    0.7481999111612437,
    0.6484148671259253,
    15.304437169365146
  ]
}

过滤B:

[.[] | { "hits": {"count": .hits.count, "percent": "TODO" }, "visitors": { "count": .visitors.count, "percent": "TODO"}, "bytes": {"count": .bytes.count, "percent": "TODO"}, "data": .data }]

Output B (located on gist)

过滤器C:(过滤器A + B)

????

Desired Output C

有关如何使用jq在bash脚本中获取输出C 的任何建议都会非常棒。我一直在调整我的齿轮几个小时,目前没有想法。

奖金问题:如何让jq在百分比上舍入2位数?

我无法进行任何数学运算,他们的Math documentation太模糊,无法提供帮助。

1 个答案:

答案 0 :(得分:3)

就您的中间结果“A”和“B”(下面用$ a和$ b表示)而言,以下过滤器会产生所需的答案。关键是transpose

($a | [.hits_percents, .visitors_percents, .bytes_percents] | transpose)
| . as $v
| reduce range(0; length) as $i
    ($b;
       .[$i].hits.percent = $v[$i][0] 
     | .[$i].visitors.percent = $v[$i][1]
     | .[$i].bytes.percent = $v[$i][2] )

可能有更好的方法来获得最终结果,但是你问两个中间结果如何组合......

奖金问题:

 # Round a (positive) percentage to two decimal places:
 def percent:
   ((1000 * .) | floor)
   | (. % 10) as $r
   | ((. / 10) | floor) as $answer
   | if $r > 4 then ($answer + 1) else $answer end
   | . / 100
   ;

这可以通过在转置后添加map(map(percent))来使用:

def percent:
  ((1000 * .) | floor)
  | (. % 10) as $r
  | ((. / 10) | floor) as $answer
  | if $r > 4 then ($answer + 1) else $answer end
  | . / 100;
($a | [.hits_percents, .visitors_percents, .bytes_percents] | transpose)
  | map(map(percent))
  | . as $v
  | reduce range(0; length) as $i
      ($b;
         .[$i].hits.percent = $v[$i][0] 
       | .[$i].visitors.percent = $v[$i][1]
       | .[$i].bytes.percent = $v[$i][2] )