Bash命令用于计算每行和每列的平均值

时间:2015-10-03 08:50:57

标签: bash terminal

假设我们有一个像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  -

3 个答案:

答案 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