How to sum a row of numbers from text file-- Bash Shell Scripting
Asked Answered
A

4

5

I'm trying to write a bash script that calculates the average of numbers by rows and columns. An example of a text file that I'm reading in is:

1 2 3 4 5
4 6 7 8 0

There is an unknown number of rows and unknown number of columns. Currently, I'm just trying to sum each row with a while loop. The desired output is:

1 2 3 4 5 Sum = 15
4 6 7 8 0 Sum = 25

And so on and so forth with each row. Currently this is the code I have:

while read i
do
  echo "num: $i"
  (( sum=$sum+$i ))
  echo "sum: $sum"
done < $2

To call the program it's stats -r test_file. "-r" indicates rows--I haven't started columns quite yet. My current code actually just takes the first number of each column and adds them together and then the rest of the numbers error out as a syntax error. It says the error comes from like 16, which is the (( sum=$sum+$i )) line but I honestly can't figure out what the problem is. I should tell you I'm extremely new to bash scripting and I have googled and searched high and low for the answer for this and can't find it. Any help is greatly appreciated.

Arne answered 8/10, 2015 at 4:46 Comment(1)
I think you want sum=$(($sum + $i))Ethnogeny
L
4

You are reading the file line by line, and summing line is not an arithmetic operation. Try this:

while read i
do
  sum=0
  for num in $i
  do
    sum=$(($sum + $num))
  done
  echo "$i Sum: $sum"
done < $2

just split each number from every line using for loop. I hope this helps.

Lind answered 8/10, 2015 at 5:19 Comment(3)
You can simplify sum=$(($sum + $num)) to ((sum = sum + num)).Bracknell
or replace sum=0 by declare -i sum=0 and use sum+=$num with bash.Degraded
This worked exactly how I wanted it! Thanks so much.Arne
F
3

Another non bash way (con: OP asked for bash, pro: does not depend on bashisms, works with floats).

awk '{c=0;for(i=1;i<=NF;++i){c+=$i};print $0, "Sum:", c}'
Foreclose answered 8/10, 2015 at 6:19 Comment(0)
M
0

Another way (not a pure bash):

while read line
do
    sum=$(sed 's/[ ]\+/+/g' <<< "$line" | bc -q)
    echo "$line Sum = $sum"
done < filename
Marxmarxian answered 8/10, 2015 at 5:28 Comment(0)
M
0

Using the numsum -r util covers the row addition, but the output format needs a little glue, by inefficiently paste-ing a few utils:

paste "$2" \
      <(yes "Sum =" | head -$(wc -l < "$2") ) \
      <(numsum -r "$2") 

Output:

1 2 3 4 5   Sum =   15
4 6 7 8 0   Sum =   25

Note -- to run the above line on a given file foo, first initialize $2 like so:

set -- "" foo
paste "$2" <(yes "Sum =" | head -$(wc -l < "$2") )  <(numsum -r "$2") 
Manicure answered 27/8, 2021 at 5:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.