luf*_*747 0 command-line json count jq
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.但是我不知道如何将这些结果重新组合到我想要的输出中.
以下假设输入包含有效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))} 
| 归档时间: | 
 | 
| 查看次数: | 1059 次 | 
| 最近记录: |