У вас есть 2 основные проблемы с вашим сценарием (но хорошая работа и хорошие усилия - вы были близки). Во-первых, вам нужно переместить ваши печатные заявления. Первый в начале END
, например,
END{
print "Student\t Total \t Letter Grade"
, а следующий в пределах for (STUDENT in CLASS){
l oop, например,
if( TOTAL < 60) {
GRADE="E"
}
print STUDENT, TOTAL, "\t" GRADE
}
}
Второй и наиболее проблемный c error - использование $1
in, e, g, HW=(EARN[$1"Homework"]/...
вместо использования STUDENT
(который является вашей переменной l oop), например, HW=(EARN[STUDENT"Homework"]/...
Наряду со вторым, в ваших расчетах, если учащийся не имеет определенной c оценки (например, "Survey"
или "Final"
, как в данных, которые вы указали в комментарии), вы получите деление на ноль, поскольку не будет соответствующей Например, POS[STUDENT"Survey"]
, и он будет принят за ноль.
Вы можете избежать этого с помощью троичной переменной, чтобы убедиться, что элементы отличны от нуля, или использовать 1
для значения, например, вместо:
FINAL=(EARN[STUDENT"Final"]/POS[STUDENT"Final"])*0.10
вы можете использовать:
FINAL=(EARN[STUDENT"Final"]/(POS[STUDENT"Final"] ? POS[STUDENT"Final"] : 1))*0.10
(это просто гарантирует, что знаменатель равен 1
, если индекс не находится в массиве POS
)
с этим изменением Вы можете использовать:
#!/bin/awk -f
BEGIN {
FS=","
OFS = "\t"
OFMT = "%.2f"
}
$4~/[0-9]/ {
EARN[$1$2]+=$4
POS[$1$2]+=$5
CLASS[$1]++
TYPE[$2]++
}
END{
print "Student\t Total \t Letter Grade"
TOTAL=0
for (STUDENT in CLASS){
HW=(EARN[STUDENT"Homework"]/(POS[STUDENT"Homework"] ? POS[STUDENT"Homework"] : 1))*0.30
LAB=(EARN[STUDENT"Lab"]/(POS[STUDENT"Lab"] ? POS[STUDENT"Lab"] : 1))*0.50
QUIZ=(EARN[STUDENT"Quiz"]/(POS[STUDENT"Quiz"] ? POS[STUDENT"Quiz"] : 1))*0.10
FINAL=(EARN[STUDENT"Final"]/(POS[STUDENT"Final"] ? POS[STUDENT"Final"] : 1))*0.10
WS=(EARN[STUDENT"Survey"]/(POS[STUDENT"Survey"] ? POS[STUDENT"Survey"] : 1))*0.10
TOTAL=(HW+LAB+QUIZ+FINAL+WS)*100
GRADE= "A"
if (TOTAL < 90) {
GRADE="B"
}
if ( TOTAL < 80){
GRADE="C"
}
if (TOTAL < 70){
GRADE="D"
}
if( TOTAL < 60) {
GRADE="E"
}
print STUDENT, TOTAL, "\t" GRADE
}
}
( примечание: Я бы использовал "F"
в качестве окончательной оценки вместо "E"
- никогда не слышал об этом ..., а также использование строчные имена для ваших пользовательских переменных)
Пример Использование / Вывод
На основе предоставленных вами данных вы получите:
$ ./calcgrades.awk grades.txt
Student Total Letter Grade
Chelsey 86.89 B
Sam 40.77 E
Дайте мне знать, если у вас есть вопросы.