Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

I understand bash and some other interpreters only perform arithmetic for integers. In the following for loop, how can I accomplish this? I've read that bc can be used but am not sure how to use bc in this situation.

total=0
for number in `cat /path/to/file`; do
        total=$(($total+$number))
done
average=$(($total/10))
echo Average is $average

file:

1.143362
1.193994
1.210489
1.210540
1.227611
1.243496
1.260872
1.276752
1.294121
1.427371
share|improve this question

marked as duplicate by BinaryZebra, Anthon, Jakuje, Jeff Schaller, dr01 Jan 30 at 15:04

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Doesn't make sense to calculate the average in every round of the loop if only the last result is used, does it? – Hauke Laging May 16 '13 at 13:15
    
ksh (ksh93) and zsh do do floating point arithmetics. – Stéphane Chazelas May 16 '13 at 14:39
    
Same question on Stack Overflow: Floating-point arithmetic in UNIX shell script – Palec Feb 10 '15 at 23:03
up vote 10 down vote accepted

You may not want to use bc for this. Perhaps awk would work better:

awk '{sum+=$1};END{print sum/NR}' /path/to/file
share|improve this answer

As tagged , here is a bash 4.0 alternative to choroba's answer, to avoid wc and sed:

bash-4.2$ mapfile -t a < file

bash-4.2$ (IFS='+'; echo "(${a[*]})/${#a[@]}") | bc -l
1.24886080000000000000
share|improve this answer
    
If it's about bash I think this is much nicer: shopt -s extglob; value=...; value="${value%%*(0)}"; if [ -z "${value##*.}" ]; then value="${value}0"; fi; echo "$value". But for next time: I note your "Organizer" badge... 8-) – Hauke Laging May 16 '13 at 14:05
    
+1 Clever use of IFS! – chepner May 16 '13 at 17:36

I usually use bc for floating point arithmetics:

file=1.txt
echo '('$(<$file)')/'$(wc -l < $file) | sed 's/ /+/g' | bc -l
share|improve this answer
term=0
file=input
for number in `cat "$file"`; do
        term="${term}+${number}"
done
total="$(echo "$term" | bc -l)"
average="$(echo "${total}/10" | bc -l)"
average="$(echo "$average" | sed -e 's/^\(.*\..*[^0]\)0*/\1/' -e p)"
echo "Total: ${total}"
echo "Average: ${average}"
share|improve this answer
    
@JohnB Then you should accept it as answer (i.e. click on the green check mark below the voting for my answer). – Hauke Laging May 16 '13 at 13:48
    
:) I guess it's not hard to tell I'm new to the site...and scripting. – John B May 16 '13 at 13:53
    
For some reason, using sed in this solution caused $average to echo twice. I substituted with cut -c-9 and it fixed it. Have no clue why. – John B May 16 '13 at 14:23
    
@JohnB You should really try the awk alternative. Don't use bash for these kind of tasks! – Bernhard May 16 '13 at 14:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.