使用jq来计数

问题描述 投票:0回答:4

如果我有一个看起来像这样的 JSON 文件,则使用 jq-1.5

[{... ,"sapm_score":40.776, ...} {..., "spam_score":17.376, ...} ...]

我如何计算

sapm_score > 40
的数量?

谢谢, 丹

更新:

我查看了输入文件,格式实际上是

{... ,"sapm_score":40.776, ...}
{..., "spam_score":17.376, ...}
...

这会改变人们的计数方式吗?

json count conditional-statements jq
4个回答
10
投票

[更新:如果输入不是数组,请参阅下面的最后一节。]

count/1

我建议定义一个

count
过滤器(也许将其放入 ~/.jq 中),也许如下所示:

 def count(s): reduce s as $_ (0;.+1);

有了这个,假设输入是一个数组,你可以写:

 count(.[] | select(.sapm_score > 40))

或者稍微更有效:

 count(.[] | (.sapm_score > 40) // empty)

这种方法(计算流中的项目数)通常优于使用

length
,因为它避免了与构造数组相关的成本。

count/2

这是您可能喜欢使用的

count
的另一个定义(也可能添加到 ~/.jq 中):

def count(stream; cond): count(stream | cond // empty);

这会计算

cond
既不是
false
也不是
null
的流元素。

现在,假设输入由数组组成,您可以简单地编写:

count(.[]; .sapm_score > 40)

“sapm_score”与“spam_score”

如果您想将“sapm_score”规范化为“spam_score”,那么(例如)您可以使用上面定义的

count/2
,如下所示:

 count(.[]; .spam_score > 40 or .sapm_score > 40)

这假设数组中的所有项目都是 JSON 对象。如果情况并非如此,那么您可能需要尝试添加“?”键名后:

count(.[]; .spam_score? > 40 or .sapm_score? > 40)

当然,以上所有内容都假设输入是有效的 JSON。如果情况并非如此,请参阅 https://github.com/stedolan/jq/wiki/FAQ#processing-not-quite-valid-json

如果输入是 JSON 对象流...

修改后的问题表明输入由 JSON 对象流组成(而最初输入被认为是 JSON 对象数组)。如果输入由 JSON 对象流组成,则可以轻松调整上述解决方案,具体取决于您拥有的 jq 版本。如果您的 jq 版本有

inputs
,则建议使用 (2)。

(1) 所有版本:使用

-s
命令行选项。

(2) 如果您的 jq 有

inputs
:使用
-n
命令行选项,并将上面的
.[]
更改为
inputs
,例如

count(inputs; .spam_score? > 40 or .sapm_score? > 40)

6
投票

过滤满足条件的项,得到长度。

map(select(.sapm_score > 40)) | length

3
投票
cat input.json | jq -c '. | select(.sapm_score > 40)' | wc -l

应该这样做。

-c
选项打印每场比赛的单行紧凑json表示,
wc -l
计算jq打印的行数。


0
投票

这是一种方法:

reduce .[] as $s(0; if $s.spam_score > 40 then .+1 else . end)

在 jqplay.org 在线尝试

如果输入不是数组而是换行符分隔对象的序列(jsonlines)

reduce inputs as $s(0; if $s.spam_score > 40 then .+1 else . end)
如果使用

-n

 标志调用 jq,则 
将起作用。这是一个例子:

$ cat data.json
{ "spam_score":40.776 }
{ "spam_score":17.376 }

$ jq -Mn 'reduce inputs as $s(0; if $s.spam_score > 40 then .+1 else . end)' data.json
1

在 tio.run 在线尝试

© www.soinside.com 2019 - 2024. All rights reserved.