如何通过密钥将JSON分组并按计数排序?

时间:2020-04-20 13:07:04

标签: json jq

我从与此类似的jsonlines文件开始

{ "kw": "foo", "age": 1}
{ "kw": "foo", "age": 1}
{ "kw": "foo", "age": 1}
{ "kw": "bar", "age": 1}
{ "kw": "bar", "age": 1}

请注意,每一行都是有效的json,但整个文件不是。

我正在寻找的输出是按关键字的出现顺序排序的关键字的有序列表。像这样:

[
    {"kw": "foo", "count": 3},
    {"kw": "bar", "count": 2}
]

我可以使用slurp选项对关键字进行分组和计数

jq --slurp '. | group_by(.kw) | .[] | {kw: .[0].kw, count: . | length }'

输出:

{"kw":"bar","count":2}
{"kw":"foo","count":3}

但是:

  • 未排序
  • 这不是有效的JSON数组

我发现一个非常愚蠢的解决方案是通过jq :)两次通过

jq --slurp --compact-output '. | group_by(.kw) | .[] | {kw: .[0].kw, count: . | length }' sample.json \
| jq --slurp --compact-output '. | sort_by(.count)'

但是我敢肯定,比我聪明的人可以找到更优雅的解决方案。

1 个答案:

答案 0 :(得分:2)

未排序

那不是很正确,group_by(.foo)在内部执行sort(.foo),因此结果以字段的排序顺序显示。参见jq Manual - group_by(path_expression)

这不是有效的JSON数组

只需将操作括在[..]中,并且前导.是可选的。所以就做

jq --slurp --compact-output '[ group_by(.kw)[] | {kw: .[0].kw, count: length } ]'

如果您要按.count进行排序,则可以进行升序排序和反转

jq --slurp --compact-output '[ group_by(.kw)[] | {kw: .[0].kw, count: length }] | sort_by(.count) | reverse'