I have a question, how i can calculate row sum in Bash without awk, only f.e with loops, but if I have in input some pipes? It seems:
| 11 14 |
| 13 7 |
Thanks!
CodePudding user response:
Say your input is in the file /tmp/input.txt
(I added a decimal and negative number just because.)
$ cat /tmp/input.txt
| 11 -14 |
| 13.4 7 |
First, remove stuff that's not a number, a space, or a newline:
$ tr -sc '[- 0-9.]\n' ' ' < /tmp/input.txt
11 -14
13.4 7
Next, remove leading/trailing spaces:
$ tr -sc '[- 0-9.]\n' ' ' < /tmp/input.txt | sed 's/^ //;s/ $//'
11 -14
13.4 7
Now, replace the remaining spaces with a
operator:
$ tr -sc '[- 0-9.]\n' ' ' < /tmp/input.txt | sed 's/^ //;s/ $//;s/ / /g'
11 -14
13.4 7
Finally, send all that into the calculator:
$ tr -sc '[- 0-9.]\n' ' ' < /tmp/input.txt | sed 's/^ //;s/ $//;s/ / /g' | bc
-3
20.4
CodePudding user response:
You can also use dc
tr -d '|' < file.txt | while read l; do echo $l p | dc; done
CodePudding user response:
You can do this entirely in bash without any additional utilities simply by reading each line into an array and then looping over each element in the array checking if the element is all digits and adding the number to the sum for the line. For example you could do:
#!/bin/bash
[ -z "$1" ] && { ## validate 1 argument given for filename
printf "error: filename required as argument.\n" >&2
exit 1
}
file="$1" ## assign argument to file
[ -s "$file" ] || { ## validate file not empty
printf "error file not found or empty.\n" >&2
exit 1
}
while read -ra arr; do ## read line into arr
sum=0 ## zero sum for line
for i in ${arr[@]}; do ## loop each element
[[ $i =~ ^[[:digit:]] $ ]] && sum=$((sum $i)) ## all digits add to sum
done
echo "sum: $sum" ## output sum
done < "$file"
(note: if negative numbers are possible, you can handle that with a simple check for zero or more '-'
characters before all digits with -*[[:digit:]]
)
You don't need to know the number of numeric elements beforehand, it simply loops over each whitespace separated word and checks if the word is comprised of all digits before adding it to the sum.
Example Use/Output
With the script in sum.sh
and your example input in file
, your output would be:
$ bash sum.sh file
sum: 25
sum: 20