假设我们有一个像marks.log这样的日志文件,内容如下所示:
Fname Lname Net Algo
Jack Miller 15 20
John Compton 12 20
Susan Wilson 13 19
我想添加一个新列,其中包含每个人的平均值,以及一个包含每个课程平均值的新行。结果必须如下所示:
Fname Lname Net Algo Avg
Jack Miller 15 20 17.5
John Compton 12 20 16
Susan Wilson 13 19 16
Average 13.3 19.6 -
答案 0 :(得分:4)
如果您的数据位于datafile.txt
,则awk的语法可能类似于:
awk '
{
# If it is the first row
if (NR==1)
print $0, "Avg";
else
# Print all fields, then the average of fields 3 & 4
print $0,($3+$4)/2;
# Get the total for field 3 and field 4
t3+=$3; t4+=$4
}
# Once that is done...
END {
# Print the final line
printf "Overall Average %.1f %.1f -\n",
# The average of field 3 (NR is the Number of Records)
t3/(NR-1),
# The average of field 4 (NR is the Number of Records)
t4/(NR-1);
}' datafile.txt
这是带注释的长版本。单线看起来像:
awk '{if (NR==1) print $0, "Avg"; else print $0,($3+$4)/2; t3+=$3; t4+=$4}END{printf "Overall Average %.1f %.1f -\n",t3/(NR-1),t4/(NR-1);}' datafile.txt
这应匹配所需的输出。
答案 1 :(得分:2)
怎么样:
gawk '{if (NR==1) { print $0, "Avg"; tn = 0; ta = 0; c = 0; } else { print $0,($3+$4)/2; tn = tn + $3; ta = ta + $4; c = c + 1; } } END {print "Average", tn/c, ta/c, c; }' <filename>
答案 2 :(得分:1)
不使用awk
的冗长解决方案可能是:
#!/bin/bash
A=0
B=0
process(){
A=$(( $A + $3 ))
B=$(( $B + $4 ))
}
get_mean(){
val=$( echo "($3 + $4)/2" | bc -l)
printf "%.1f" $val
}
line_id=0
while read line
do
line_id=$(( $line_id + 1 ))
if [ $line_id -le 1 ]; then
echo "Fname Lname Net Algo Avg"
continue
fi
process $line
mean=$(get_mean $line)
echo $line $mean
done
A=$(echo "$A/($line_id-1)" | bc -l)
B=$(echo "$B/($line_id-1)" | bc -l)
printf "Average\t\t%.1f %.1f -" $A $B
然后可以将此脚本调用为./test.sh < input
。