Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

bash

shell

sum

rows

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.

like image 881
clb Avatar asked Oct 08 '15 04:10

clb


People also ask

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.

What is $@ in bash script?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


2 Answers

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.

like image 177
Kadir Avatar answered Sep 21 '22 13:09

Kadir


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}'
like image 29
bufh Avatar answered Sep 20 '22 13:09

bufh