jq如何根据值从唯一键中选择

时间:2019-03-11 19:28:43

标签: json command-line jq data-manipulation

我最近一直在学习有关JSON的更多信息,偶然发现了“ jq”命令行JSON处理器。我正在尝试合并有关Github存储库中克隆的多个json文件。其中一些日期重叠,并且由于它们是在一天的不同时间访问的,因此其计数和唯一值略有不同。这是一个示例:

[
  {
    "timestamp": "2018-12-24T00:00:00Z",
    "count": 1,
    "uniques": 1
  },
  {
    "timestamp": "2018-12-24T00:00:00Z",
    "count": 2,
    "uniques": 1
  },
  {
    "timestamp": "2018-12-24T00:00:00Z",
    "count": 3,
    "uniques": 2
  },
  {
    "timestamp": "2018-12-25T00:00:00Z",
    "count": 12,
    "uniques": 5
  },
  {
    "timestamp": "2018-12-25T00:00:00Z",
    "count": 15,
    "uniques": 9
  }
]

生成的代码应查看时间戳,确定其是否唯一,如果不是,则保留包含最大“计数”的对象。所需输出的示例如下:

[
  {
    "timestamp": "2018-12-24T00:00:00Z",
    "count": 3,
    "uniques": 2
  },
  {
    "timestamp": "2018-12-25T00:00:00Z",
    "count": 15,
    "uniques": 9
  }
]

“ jq”似乎是一个非常有用的工具,我已经设法在其他一些情况下使用它,但是还无法弄清楚是否或如何以这种方式使用它。任何帮助(或方向)将不胜感激!

1 个答案:

答案 0 :(得分:0)

使用以下两个通用辅助函数可以获得简单而有效的解决方案:

def aggregate_by(s; f; g):
  reduce s as $x  (null; .[$x|f] += [$x|g]);

def max_by(s; f):
  reduce s as $s (null;
    if . == null then {s: $s, m: ($s|f)}
    else  ($s|f) as $m
    | if $m > .m then {s: $s, m: $m} else . end
    end)
  | .s ;

有了这些,解决方案就是两条线:

[ aggregate_by(.[]; .timestamp; .)[]
  | max_by(.[]; .count) ]