json数据:
{testId: '1' studentId:{'s1':{score: 20} 's2':{score: 80}}}
{testId: '2' studentId:{'s1':{score: 60} 's2':{score: 70}}}
{testId: '3' studentId:{'s5':{score: 40} 's7':{score: 30}}}
...
我想用JQ告诉我有多少学生获得了分数> x,每次测试。
因此对于上面的输入和x = 50,输出:
{testId: '1' numStudents:1}
{testId: '2' numStudents:2}
{testId: '3' numStudents:0}
我能够生成所有达到>的学生的列表。
每次测试50次{testId, studentId: .studentId[]?} | select(.studentId.score>50)
此命令创建一个对象列表,其中每个对象包含testId,studentId和score,其中所有分数都大于50.但我不知道如何将这些结果重新组合到我想要的输出中。
答案 0 :(得分:5)
以下假设输入包含有效JSON对象流。
一种方法是使用add
:
$ jq '{testId, numStudents: ([select(.studentId[].score > 50) | 1] | add // 0)}'
使用给定的输入(在进行了更正之后),输出将是:
{
"testId": "1",
"numStudents": 1
}
{
"testId": "2",
"numStudents": 2
}
{
"testId": "3",
"numStudents": 0
}
另一种方法是使用length
,例如使用此过滤器:
{testId,
numStudents: ([select(.studentId[].score > 50) ] | length)}
但是,如果您不介意添加' def'那么最佳解决方案(例如,因为它不涉及构建中间数组)将沿着以下几行:
def count(s): reduce s as $i (0; .+1);
{testId, numStudents: count(select(.studentId[].score > 50))}