19

I have a series piped greps, awks and seds which produce a list of numbers, one on each line. Something like this:

1.13
3.59 
1.23

How can i pipe this to something which will output the average, max, and min?

JavaRocky
  • 481
  • 2
  • 4
  • 15

5 Answers5

29

Since you're already using awk

blahblahblah | awk '{if(min==""){min=max=$1}; if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {print total/count, max, min}'
DerfK
  • 19,493
  • 2
  • 38
  • 54
4

I find this program useful for generating stats on lists of numbers at the command line: http://web.cs.wpi.edu/~claypool/misc/stats/stats.html

ddrown
  • 81
  • 2
0

You can use ministat:

$ ministat -n
1.13
3.59 
1.23

x <stdin>
    N           Min           Max        Median           Avg        Stddev
x   3          1.13          3.59          1.23     1.9833333     1.3923122

And with tail, sed and cut you can extract a single field, e.g. ministat -n | tail -1 | sed -r 's/ +/ /g;' | cut -d\ -f 6 gives you the average (since it: takes the last line; removes extra spaces; then takes the sixth non-space token on the line).

einpoklum
  • 1,652
  • 3
  • 21
  • 31
0

There is also simple-r, which can do almost everything that R can, but with less keystrokes:

https://code.google.com/p/simple-r/

To calculate average, max, and min, one would have to type one of:

r summary file.txt
r summary - < file.txt
cat file.txt | r summary -
0

With a tip of the hat to @DerfK:

perl -lane '$n=$F[0]; if(not defined $min){$min=$max=$n}; if($n>$max){$max=$n}; if($n<$min){$min=$n}; $total+=$n; $count+=1; END{print $total/$count." $max $min"}'

$F[0] is the value in the first (0'th) field of each line

If your input data is comma separated, add the -F, modifier before -lane

Chris Koknat
  • 111
  • 3