我需要用JQ计算每个组中的对象数,但仅适用于N个最新对象。
样本输入,N = 3:
{"modified":"Mon Sep 25 14:20:00 +0000 2018","object_id":1,"group_id":"C"}
{"modified":"Mon Sep 25 14:23:00 +0000 2018","object_id":2,"group_id":"A"}
{"modified":"Mon Sep 25 14:21:00 +0000 2018","object_id":3,"group_id":"B"}
{"modified":"Mon Sep 25 14:22:00 +0000 2018","object_id":4,"group_id":"A"}
预期输出:
{"A",2}
{"B",1}
我什至没有选择一个可以保留对象结构的基于日期的子集:这是我设法实现的最好结果:
[
.modified |= strptime("%a %b %d %H:%M:%S %z %Y") |
.modified |= mktime |
.modified |= strftime("%Y-%m-%d %H:%M:%S")
] |
sort_by(.modified) |
.[] |
{modified, object_id, group_id}
由于某些原因,结果仍未排序。
我也未能将此类列表转换为仅选择N个最新条目的数组。
然后,我需要以某种方式计算每个组中的对象数。
总的来说,对于对象的数组和列表如何相互转换以及如何修改其某些字段,然后仅提取所需的字段,我似乎需要一个非常直观的解释。不幸的是,到目前为止,我发现的教程没有帮助。
答案 0 :(得分:3)
假设您的输入文件是:
cat file
{"modified":"Mon Sep 25 14:20:00 +0000 2018","object_id":1,"class_id":"C"}
{"modified":"Mon Sep 25 14:23:00 +0000 2018","object_id":2,"class_id":"A"}
{"modified":"Mon Sep 25 14:21:00 +0000 2018","object_id":3,"class_id":"B"}
{"modified":"Mon Sep 25 14:22:00 +0000 2018","object_id":4,"class_id":"A"}
您可以尝试以下操作:
<file jq -s '
[ .[] |
(.modified |= (strptime("%a %b %d %H:%M:%S +0000 %Y") | mktime))
] |
sort_by(.modified) | # sort using converted time
.[-3:] | # take the last 3
group_by(.class_id) | # group ids together
.[] |
{(.[0].class_id): length}' # create the object using the id name and table length
{
"A": 2
}
{
"B": 1
}
请注意,在我的系统上,%z
中的选项strptime
不起作用。因此,我将其替换为+0000
(无论如何在时间转换中都没有使用)。
答案 1 :(得分:2)
accepted answer使用-s
命令行选项,该选项要求整个输入数据都适合内存。对于非常大的数据集,这可能是不可能的。
自从jq 1.5(在2015年)发布以来,已经有了替代方案。因此,在这里提出了一种使用inputs
的内存有效解决方案。
关键功能封装在以下jq过滤器中:
# Return an array of n items as if by
# [stream] | sort_by(filter) | .[-n:]
def maxn(stream; filter; n):
def maxn:
sort_by(filter) | .[-n :];
reduce stream as $x ([]; . + [$x] | maxn);
现在只需另外三行就可以得到当前问题的解决方案(N == 3):
maxn(inputs; .modified | strptime("%a %b %d %H:%M:%S +0000 %Y") | mktime; 3)
| group_by(.class_id)[]
| {(.[0].class_id): length}
请注意,这假定使用了-n命令行选项。如果省略,则输入的第一行将被忽略。
对于大型数据集,如果N的值也很大,则可能需要对上面的内容进行调整以使用jq的支持二进制搜索(bsearch
而不是sort_by
的麻烦。类似地,值得缓存mktime
值。