使用jq按指定字节范围汇总键值对JSON的值
使用jq按指定字节范围汇总键值对JSON的值
嘿,我来帮你搞定这个用jq按字节范围汇总JSON数据的需求!先明确下需求:我们有一组会话对应的字节数,要按0-1MB、1-2MB…12-13MB(左闭右开)的范围,统计每个范围内的总字节数,还可以优化成人类可读的格式。
核心实现思路
我们可以用jq的reduce迭代每个范围,筛选对应区间的数值并求和。先定义好MB和字节的换算关系,再列出所有需要统计的范围,最后遍历计算每个范围的总和。
第一步:准备JSON数据
先把你的JSON保存到data.json文件里:
{ "session1": 128, "session2": 1048596, "session3": 3145728, "session4": 3145828, "session5": 11534338, "session6": 11544336, "session7": 2097252 }
第二步:编写jq脚本
创建一个sum-by-range.jq脚本,内容如下:
# 辅助函数:将MB转换为字节数 def mb(n): n * 1048576; # 定义所有需要统计的范围([下限MB, 上限MB]) def ranges: [ [0,1], [1,2], [2,3], [3,4], [4,5], [5,6], [6,7], [7,8], [8,9], [9,10], [10,11], [11,12], [12,13] ]; # 遍历范围,分组求和 . as $data | reduce ranges[] as $range ({}; # 计算当前范围的字节上下限 lower = mb($range[0]) | upper = mb($range[1]) # 筛选当前范围内的数值并求和 | sum = ($data | to_entries[] | select(.value >= lower and .value < upper) | .value) # 只添加有数据的范围到结果 | if sum > 0 then . + { "\($range[0])-\($range[1])MB": sum } else . end )
第三步:运行脚本得到结果
在终端执行以下命令:
jq -f sum-by-range.jq data.json
输出结果和你预期的一致:
{ "0-1MB": 128, "1-2MB": 1048596, "2-3MB": 2097252, "3-4MB": 6291556, "11-12MB": 23078674 }
可选:输出人类可读格式
如果想让结果更直观,把字节数转换成MB格式,可以修改脚本中添加结果的部分:
# 替换原来的if语句部分 | if sum > 0 then . + { "\($range[0])-\($range[1])MB": "\( (sum / 1048576) | round(2)) MB (\(sum) bytes)" } else . end
修改后运行,输出会变成:
{ "0-1MB": "0.00 MB (128 bytes)", "1-2MB": "1.00 MB (1048596 bytes)", "2-3MB": "2.00 MB (2097252 bytes)", "3-4MB": "6.00 MB (6291556 bytes)", "11-12MB": "22.00 MB (23078674 bytes)" }
小提示
- 如果需要调整范围,直接修改
ranges数组里的元素即可,比如新增[13,14]范围。 - 要是想保留更多小数位数,把
round(2)改成round(4)就能保留四位小数啦。
备注:内容来源于stack exchange,提问作者Jojo Thomas
相关产品推荐
相关产品推荐

