3

I need to sum numbers from a file line by line.

The file:

1.0
0.46
0.67

I want to sum, then divide 3.

I currently have:

while IFS= read -r var
do
   x=$(($var + $x)) | bc -l
done < "file.txt"
echo "$x / 3"

My error:

-bash: 1.0 + 0: syntax error: invalid arithmetic operator (error token is ".0 + 0")
Melih
  • 147
  • 1
  • 7

4 Answers4

7

Bash/shell arithmetic can't handle floating point arithmetic. You can accomplish your task using awk:

awk '{sum= sum+$1} END {print sum/3}' file

This will read through your file and add each line to sum. After it completes reading the file, it will print sum divided by 3.

fra-san
  • 10,205
  • 2
  • 22
  • 43
jesse_b
  • 37,005
3

Just for fun

$ paste -sd+ file | dc -e2k0 -f- -e+3/p
.71

Here we're using the dc reverse Polish calculator: to sum the numbers we want to write them as

1.0 0.46 + 0.67 +

however it's easier to prime the stack with zero (-e0) and make it

0 1.0+0.46+0.67 +

since the body of the sum can then be generated by a simple paste command:

$ paste -sd+ file
1.0+0.46+0.67

Lastly we need the final postfix + for the sum and the postfix division which we can write in another -e command (not forgetting to print the final result) as -e+3/p.

The last wrinkle is that although dc can work in arbitrary precision, division defaults to a precision of 0 and hence will return an integer result. We can change that using the 2k command which pushes 2 to the stack and then pops it and uses the result to set the precision.

Putting it all together:

paste -sd+ file | dc -e2k0 -f- -e+3/p
steeldriver
  • 81,074
0

Try this:

x=0
while IFS= read -r var; do
    x="$(echo "$var + $x" | bc -l)"
done < "file.txt"
echo "$x / 3" | bc -l
  1. x was not defined.
  2. You need an echo for bc to work (not mixed bash arithmetic).
Freddy
  • 25,565
0

For summing the numbers, numsum from the num-utils package will do exactly that in one go:

x=$(numsum file.txt)

It is happy to deal with decimal numbers.

For the division afterwards numprocess from the same package can help:

numsum file.txt | numprocess /%3/

% is how numprocess represents division, and the slashes are an oddity of its argument structure.

Michael Homer
  • 76,565