2014-07-21 94 views
2

声明:这不是作业,这是我为工作而做的事情的消毒版本。复杂的jq过滤器

我想用jq过滤一些json数据,并且希望为我的过滤器中的每个匹配记录返回一个对象。以下是我正在做的事情的文字描述:“给定一个包含学生列表,一些个人信息和他们的成绩的JSON对象,为每个接收了A的学生返回一个名称,年龄和累计GPA列表CSC101“。

这里的测试JSON对象(程序输入):

{ 
    "students": [ 
     {"name": "John", "age": "19", "gender": "m", "from": "Tampa, FL", "cum_gpa": "3.83", "semesters": [ 
      {"name": "201302", "gpa": "3.67", "grades": {"CSC101": "A", "MAT101": "A", "PSY101": "B"}}, 
      {"name": "201401", "gpa": "4.00", "grades": {"CSC201": "A", "MAT201": "A", "HIS101": "A"}} 
     ]}, 
     {"name": "Mary", "age": "20", "gender": "f", "from": "Chicago, IL", "cum_gpa": "3.50", "semesters": [ 
      {"name": "201302", "gpa": "4.00", "grades": {"CSC101": "A", "MAT101": "A", "ECO101": "A"}}, 
      {"name": "201401", "gpa": "3.00", "grades": {"CSC201": "B", "MAT201": "B", "HUM101": "B"}} 
     ]}, 
     {"name": "Dan", "age": "20", "gender": "m", "from": "Seattle, WA", "cum_gpa": "3.33", "semesters": [ 
      {"name": "201302", "gpa": "3.33", "grades": {"CHE101": "B", "MAT101": "A", "PSY101": "B"}}, 
      {"name": "201401", "gpa": "3.33", "grades": {"CHE201": "A", "MAT201": "A", "HUM101": "C"}} 
     ]} 
    ] 
} 

这里是我当前的过滤器表达和结果:

cat test.json |jq -c '.students[]|select(.semesters[].grades.CSC101 == "A")|{name: .name, age: .age, gpa: .cum_gpa, CSC101: .semesters[].grades.CSC101}' 
{"name":"John","age":"19","gpa":"3.83","CSC101":"A"} 
{"name":"John","age":"19","gpa":"3.83","CSC101":null} 
{"name":"Mary","age":"20","gpa":"3.50","CSC101":"A"} 
{"name":"Mary","age":"20","gpa":"3.50","CSC101":null} 

它的工作排序的,但它会产生额外的输出。我只希望它能让学生拥有CSC101入学的学分,但是它会将所有学期的学生退还给参加CSC101的任何学生。有什么建议么?

回答

4

试试这个过滤器:

.students | map(
    { 
     name, 
     age, 
     gpa: .cum_gpa, 
     CSC101: .semesters | map(.grades) | add | .CSC101 
    } 
    | 
    select(.CSC101 == "A") 
) 

的想法是从合并为每个学生都学期各年级和抢CSC101档次。然后筛选出具有A等级的学生。

这导致:

[ 
    { 
    "name": "John", 
    "age": "19", 
    "gpa": "3.83", 
    "CSC101": "A" 
    }, 
    { 
    "name": "Mary", 
    "age": "20", 
    "gpa": "3.50", 
    "CSC101": "A" 
    } 
] 
+0

上jqplay.org尝试此,让 “错误:语法错误,意外QQSTRING_START” –

+0

检查输入。我在jqplay.org上写了这个,并得到了结果。这太糟糕了,我们无法链接到那里的特定结果。 –

+0

不确定过滤器的单行版本是否是问题,因为上面的示例是多行的。这是我复制的:.students | map({name,age,gpa:.cum_gpa,CSC101:.semesters | map(.grades)| add | .CSC101})|地图(选择(.CSC101 == A“)) –