Json 用jq计数
如果我有一个JSON文件Json 用jq计数,json,count,conditional-statements,jq,Json,Count,Conditional Statements,Jq,如果我有一个JSON文件 [{... ,"sapm_score":40.776, ...} {..., "spam_score":17.376, ...} ...] 我如何计算sapm评分>40的分数 谢谢, 丹 更新: 我查看了输入文件,其格式实际上是 {... ,"sapm_score":40.776, ...} {..., "spam_score":17.376, ...} ... 这是否会改变计数方式?[更新:如果输入不是数组,请参阅下面的最后一节。] count/1 我建议您定义一
[{... ,"sapm_score":40.776, ...} {..., "spam_score":17.376, ...} ...]
我如何计算sapm评分>40的分数
谢谢,
丹
更新:
我查看了输入文件,其格式实际上是
{... ,"sapm_score":40.776, ...}
{..., "spam_score":17.376, ...}
...
这是否会改变计数方式?[更新:如果输入不是数组,请参阅下面的最后一节。]
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中):
这对cond
既不是false也不是null
的流元素进行计数
现在,假设输入由一个数组组成,您只需编写:
count(.[]; .sapm_score > 40)
“sapm_分数”与“垃圾邮件_分数”
如果您希望将“sapm_分数”标准化为“spam_分数”,那么(例如),您可以使用上文定义的count/2
,如下所示:
count(.[]; .spam_score > 40 or .sapm_score > 40)
这假设数组中的所有项都是JSON对象。如果情况并非如此,则您可能希望尝试在键名称后添加“?”:
count(.[]; .spam_score? > 40 or .sapm_score? > 40)
当然,以上所有假设输入是有效的JSON。如果情况并非如此,请参阅
如果输入是JSON对象流。。。
修改后的问题指出输入由JSON对象流组成(而最初的输入被称为JSON对象数组)。如果输入由JSON对象流组成,那么根据您拥有的jq版本,可以轻松地调整上述解决方案。如果您的jq版本具有输入
,则建议使用(2)
(1) 所有版本:使用-s
命令行选项
(2) 如果jq有输入
:使用-n
命令行选项,并将上面的[]
更改为输入
,例如
count(inputs; .spam_score? > 40 or .sapm_score? > 40)
过滤满足条件的项目,然后获取长度
map(select(.sapm_score > 40)) | length
这里有一个方法:
reduce .[] 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
实际上在发布之前就试过了。Get'jq:error(at:1):无法为文件中每一行的字符串“spam_score”编制索引。@DanEhrlich-更新是否令人满意地解决了您的问题?如果输入是以换行符分隔的对象序列而不是数组,则此处的解决方案可以使用输入
而不是[]
如果jq通过了-n
标志。鉴于垃圾邮件评分
有意义,那么sapm评分是正确的还是打字错误?如果它是正确的,您是否需要按照建议进行规范化?如果只是打字错误,你介意更正一下问题中的信息吗?
reduce inputs as $s(0; if $s.spam_score > 40 then .+1 else . end)
$ 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