1

The task is that if input numbers:

4
1
2
9
8

Output=(sum of all except first_number_in_series)/first_number in series Then output average should be 1+2+9+8/(first_number_in series)=20/4=5

I have tried the following code, however not able to achieve the task. I will be grateful if anyone can point out the mistake.

#!/bin/bash
sum=0
count=1
for x in $*
do
    if [ $count -eq 1 ]
    then
        p=$x
    else
        sum=$(($sum + $x))
    fi
    ((count++))
done
echo "scale=3;$sum/$p" | bc
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
frp farhan
  • 207
  • 2
  • 11

4 Answers4

2

Since you need floating point calculation, you will end up using bc, or awk, anyways. Why not use Awk to solve the whole problem? Here is a Awk only solution, I used n for numerator and d for denominator:

$ printf "4\n1\n2\n9\n8\n" | awk '{if (NR == 1) {d = $0}; if (NR != 1) {n += $0}} END{printf "%.03f\n", n/(d*1.0)}'
5.000
Vikyboss
  • 296
  • 1
  • 4
1

A simple POSIX solution:

average() { printf '%s\n' 'scale=2' "($*)/$#" | tr ' ' + | bc;}

Then run it like so:

average 4 1 2 9 8

Output: 4.80

Wildcard
  • 35,316
  • 26
  • 130
  • 258
0

You were including the first number in the sum and you wrote a bad condition:

if [ count -eq "1" ]

instead of

if [ $count -eq 1 ]

$ operator let you access to a variable and you were using 1 as a String instead of a integer.

#!/bin/bash
read n
p=$n
sum=0
count=1
while [ $count -le $p ]
do
    read n
    x=$n
    count=$(($count + 1))
    sum=$(($sum + $x))
done
result=`echo $sum $p | awk '{printf "%.3f", $1/$2 }'`
echo $result
eduardogr
  • 215
  • 1
  • 7
0

You failed to say that the numbers are given to the script in the stdin.

For that, this code will work:

#!/bin/bash
readarray -t x
count="${x[0]}" ; unset x[0]
for y in ${x[@]}; do (( sum+=y )); done
a="$(echo "scale=8; $sum/$count" | bc)"
LC_ALL=C printf '%0.3f\n' "$a"

Test it as this:

$ printf '%s\n' 4 1 2 9 8 | ./script
5.000
$ printf '%s\n' 6 1 2 9 8 13 25 | ./script
9.667
  • What is the difference between stdin and normal inputs?? I am new to bash, it will be greatful if u can clearify this for me...thnx – frp farhan Feb 08 '16 at 03:37
  • Also, in the above code if the output is 9.6666, then answer is expected to be 9.667,then how to achieve this task in ur testcase 2 wherein the answer is 9.6666 how to display rounded off value such as 9.667? – frp farhan Feb 08 '16 at 03:40
  • The difference is like the difference between this two lines: `./script 1 2 3 4` and `echo 1 2 3 4 | ./script`. The first supply the arguments in the array of "positional arguments" (similar to c ARGV[]), the second supply the values in the stdin input (no ARGV is set). –  Feb 08 '16 at 04:42
  • Rounding is a very slippery slope. You can get what you ask for with printf: `LC_ALL=C; a=9.666666; printf '%0.3f' "$a"` (output 9.667), but even that is bound to fail in some other corner cases. –  Feb 08 '16 at 04:48
  • In which cases will it result into failure??? and in our code, where shall i include printf '%0.3f'?? – frp farhan Feb 08 '16 at 05:32
  • [Read this](https://unix.stackexchange.com/questions/240112/weird-float-rounding-behavior-with-printf) (as one example) and code edited in the answer. Something else still? –  Feb 08 '16 at 06:03
  • thnx dear....for further any queries will surely discuss with u...thnx a lot...wish u a vry happy and prosperous future ahead!!! also for sed and awk utilities pls guide me any good material or reference from which i can prepare them...thnx once again – frp farhan Feb 08 '16 at 06:22