I want to loaded a temporary files with the bunch of numbers from input file. The format of the script is "testing -row/-col [input file]". The input file mostly just a bunch of random numbers like
1 2 3 4
3 3 5 6
9 4 4 2
My code below is trying to grab this input file as argument and then "cat" these numbers into a new temporary files. From there, I'm trying to find average value of the row from this temporary files.
FILENAME=$2
TMP=./TMP2.$$
cat $FILENAME > $TMP
#average row
function avg_row {
while read -a row
do
total=0
sum=0
for i in "${rows[@]}"
do
eum=`expr $sum + $i`
total=`expr $total + 1`
done
average=`expr $sum / $total`
echo $average
done < $TMP
}
However, even though when I "cat" the TMP files it display exactly the same like testing_file, when I run the script it prints
expr: division by zero
expr: division by zero
expr: division by zero
Any suggestions or idea on why this could happen? Thank you.
Two issues:
Your function reads in array row
but then attempts to access a nonexistent array rows
. Because rows
has no entries, total
is never incremented and the division is division-by-zero.
This line updates eum
, not sum
:
eum=`expr $sum + $i`
Also, it is not clear why the contents of $FILENAME are copied before they are read. I will assume that you have a good reason for this.
A corrected function looks like:
function avg_row {
while read -a row
do
total=0
sum=0
for i in "${row[@]}"
do
sum=`expr $sum + $i`
total=`expr $total + 1`
done
average=`expr $sum / $total`
echo $average
done < $TMP
This produces the output:
$ avg_row
2
4
4
Both backticks and expr
are archaic. A more modern bash version of the function is:
avg_row2() {
while read -a row
do
sum=0
for i in "${row[@]}"
do
((sum += i))
done
echo $((sum / ${#row[@]}))
done < $TMP
}
This produces the same output as before:
$ avg_row2
2
4
4
The same thing can be accomplished in awk:
$ awk '{s=0; for (i=1;i<=NF;i++) s+=$i; print int(s/NF);}' filename
2
4
4
Unlike bash, awk can do floating point arithmetic:
$ awk '{s=0; for (i=1;i<=NF;i++) s+=$i; print s/NF;}' filename
2.5
4.25
4.75