学生成绩表单如下:
1 Name,Team,First Test, Second Test, Third Test 2 Tom,Red,5,17,22 3 Joe,Green,3,14,22 4 Maria,Blue,6,18,21 5 Fred,Blue,2,15,23 6 Carlos,Red,-1,15,24 7 Phuong,Green,7,19,21 8 Enrique,Green,3,16,20 9 Nancy,Red,9,12,24
编写一个awk脚本用来计算每个人的平均成绩,每次测试的平均成绩和没组队的平均成绩。如果某次成绩为负数,则表示此人错过了测试,那计算平均成绩时排除此人再计算。输出的格式如下,在名字的列表中,名字是10个宽度且左对齐(提示printf中使用%-10s格式),而平均值是7个字符宽度,右边两个右对齐的小数。
1 Name Average 2 ---- ------- 3 Tom 14.67 4 Joe 13.00 5 Maria 15.00 6 Fred 13.33 7 Carlos 19.50 8 Phuong 15.67 9 Enrique 13.00 10 Nancy 15.00 11 ------------------ 12 Average for Test 1 : 5 13 Average for Test 2 : 15.75 14 Average for Test 3 : 22.125 15 ------------------- 16 Average for Red Team: 16 17 Average for Blue Team: 14.1667 18 Average for Green Team: 13.8889
脚本如下:
1 awk -F, 'BEGIN{ 2 printf "%-10s %s ","Name","Average" 3 printf "%-10s %s ","----","-------" 4 } 5 NR>1{ 6 sum=0 7 n=0 8 for (i=3;i<=5;i++){ 9 if ($i>0){ 10 n++ 11 sum=sum+$i 12 testcount[i-2]++ 13 testtotal[i-2]+=$i 14 teamcount[$2]++ 15 teamtotal[$2]+=$i 16 } 17 } 18 printf "%-10s %7.2f ",$1,sum/n 19 } 20 END{ 21 print "------------------" 22 for (j=1;j<=3;j++){ 23 print "Average for Test "j" : "testtotal[j]/testcount[j] 24 } 25 print "-------------------" 26 for (t in teamcount){ 27 print "Average for "t" Team: "teamtotal[t]/teamcount[t] 28 } 29 }' teamlist.txt
解析:
1.awk的BEGIN语句输出表的两个列名。
2.NR>1表示只处理从第二行开始的数据。
3.sum=0,n=0,初始化三个测试总成绩和参加的次数。
4.定义一个for循环,循环处理三次测试数据。
5.判断成绩大于0才处理此次测试。
6.为计算每个人的平均成绩,用变量n记录测试次数,变量sum累计三次的成绩,接着下面用printf格式化输出每个人的平均成绩;为计算三个测试中每次的平均成绩,以i-2作为索引(即i-2次测试),数组testcount记录某次测试参加的人数,数组testtotal记录某次测试的总成绩;为计算每个组的平均成绩,以第二列组名做为索引,数组teamcount记录某组参加测试的人数,数组teamtotal记录某组的总成绩。
7.在END语句中用两个for循环语句分别输出每次测试及每组测试的平均成绩。