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.

for number in `cat /path/to/file`; do
echo Average is $average


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
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:

echo '('$(<$file)')/'$(wc -l < $file) | sed 's/ /+/g' | bc -l
share|improve this answer
for number in `cat "$file"`; do
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.