查找给定文件中每个学生的总分

查找给定文件中每个学生的总分

文件:

Name: Rad
Eng: 94
Tam: 98
Mat: 98
Soc: 98
Sci: 80
Name: Din
Eng: 87
Tam: 89
Mat: 78
Soc: 87
Sci: 34
Name: Hardy
Eng: 78
Tam: 87
Mat: 23
Soc: 34
Sci: 98

剧本 :

#!/bin/bash
file=$1
num=$2
n=`wc -l < $file`
it=$((n/num))
echo $n
echo $it
awk -v numm="$num" '{if (NR<=numm){T+=$2}}END{print T}' $file

我的上述脚本可以为第一个学生生成总数。我也想找到剩余两名学生的总分。有人可以帮我弄这个吗?

答案1

awk '/^Name:/ { if (name) printf("%s, score = %d\n", name, score); name = $2; score = 0; next }
              { score += $2 }
     END      { printf("%s, score = %d\n", name, score) }' file

结果:

Rad, score = 468
Din, score = 375
Hardy, score = 320

awk对以字符串 开头的每一行执行第一个块Name:。如果name变量有值,则前一个学生的总分将与该学生的姓名一起打印。然后名称设置为当前行的第二个字段,分数重置为零。然后脚本立即继续下一个输入行。

第二个块针对前一个块未处理的每一行输入执行。它只是将分数添加到score变量的值上。

最后一个块在读取文件的最后一行后执行,并模仿第一个块中完成的输出。这是为了输出最后一个学生的结果。


复制代码很丑陋,所以这里有一个使用函数来执行输出的解决方案:

awk 'function output() { if (name) printf("%s, score = %d\n", name, score) } 
     /^Name:/          { output(); name = $2; score = 0; next }
                       { score += $2 }
     END               { output() }' file

这不是问题的一部分,但可能很有趣:

awk 'function output() { if (name) printf("%s\t score = %3d, mean = %.1f\n", name, score, score/count) } 
     /^Name:/          { output(); name = $2; score = count = 0; next }
                       { score += $2; ++count }
     END               { output() }' file

输出:

Rad      score = 468, mean = 93.6
Din      score = 375, mean = 75.0
Hardy    score = 320, mean = 64.0

答案2

您可以搜索Name,每次找到后,您都会转到下一numm行并对分数求和:

#!/bin/bash
file=$1
num=$2
awk -v numm="$num" '
/Name/{
  mark = 0;
  printf("%s ",$2);
  for ( i=0; i<numm ; i++){
    getline;
    mark += $2;
  }
  printf("%d\n", mark);
}' $file

结果:

Rad 468
Din 375
Hardy 320

答案3

请找到以下命令来实现相同的效果

命令:

 for i in Rad Din Hardy
> do
> sed -n "/$i/,+5p" p.txt| awk -F ":" '{print $2}'| sed "/$i/d"| awk -v i="$i" 'BEGIN{sum=0}{sum=sum+$1}END {print "Total marks of " i " "  sum}'
> done

输出

Total marks of Rad 468
Total marks of Din 375
Total marks of Hardy 320

相关内容