0

How to calculate the average in linux?

 I have a file like this: ID Math Sci Eng Average 230 70 - 50 123 50 50 60 223 - 80 90 

I need the output like this:

 ID Math Sci Eng Average 230 70 - 50 60 123 50 50 60 53.33 223 - 80 90 85 

I am using this code, but I am only able to get the total:

awk '/^[0-9]/ {for (i=2; i<=NF; i++) {tot+=$i}; avg=tot/cnt[i]; print $1 "\t" avg}' 

I calculated total using the above; and thought that I will be able to count the no. but its giving me an error .. Please help me, I am new to this field .. Thanks :)

3
  • 1
    Do you want to include error message as well? Commented Nov 26, 2011 at 5:52
  • 3
    awk? you'd be better off using Ruby or Perl Commented Nov 26, 2011 at 6:23
  • perl -lpe 'if(/^\d/){local($a,@_,$s,$")=split/\s+/;map{$s+=$_;++$"if/\d/}@_;$_.="\t".$s/$"}' Commented Jan 27, 2012 at 10:44

3 Answers 3

1
awk '/^[0-9]/ { tot = 0; count = 0; for (i = 2; i <= NF; i++) { to += $i; if($i + 0 == $i){ count++; } } avg = tot/count; print $0,avg; }' 

Might be better to put it into a script.

Sign up to request clarification or add additional context in comments.

2 Comments

tot/(NF - 1) produces the wrong average for students who have not taken all three classes (e.g., ID #230). You'll need to count the numberish scores and divide by that.
Can you please tel me how to count for each row?
1

AWK Script:

awk ' /^[0-9]/{ total=0; count=0; for(i=2;i<=NF;i++) { total=total+$i; if($i!="-") { count++; } } print $0"\t\t" total/count } !/[0-9]/{ print $0; next }' avg.txt 

Test:

[jaypal~/Temp]$ cat avg.txt ID Math Sci Eng Average 230 70 - 50 123 50 50 60 223 - 80 90 [jaypal:~/Temp] awk ' /^[0-9]/{ total=0; count=0; for(i=2;i<=NF;i++) { total=total+$i; if($i!="-") { count++; } } print $0"\t\t" total/count } !/[0-9]/{ print $0; next }' avg.txt ID Math Sci Eng Average 230 70 - 50 60 123 50 50 60 53.3333 223 - 80 90 85 

Comments

0

in Ruby:

filename = '/tmp/input' outfile = '/tmp/output' first = true out = File.open(outfile, 'w') File.readlines( filename ).each do |line| arr = line.split if first out.puts line first = false else sum = 0 arr[1..3].each{|x| sum += x.to_i } denom = arr[1..3].count{|x| x =~ /\d+/ } avg = sum / denom.to_f arr << avg out.puts arr.join(' '*10) end end out.close 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.