Home > database >  Sum of n numbers entered by keyboard in bash script
Sum of n numbers entered by keyboard in bash script

Time:11-28

First, sorry for "my english".

I have to make a script that is asking me for numbers passed to keyboard and adding them up and showing the accumulated amount. And the program will end when you enter a negative number.

I have made the following script which works but I am not convinced with the use of seq in the for to use that as an accumulator, it has not occurred to me to do it any other way.

Ways to make it more ... Elegant ??

Edit: Elegant is not the word, but if what I am doing is correct in bash or there is a way to do it "normative" or "less strange"...

Thanks!

#!/bin/bash
#accumulated sum of numbers


i=0
sum=0
while [[ true ]]; do

echo "Insert a number: "
read num

if (($num < 0)); then
echo "Negative number, exit..."
break
fi

for i in $(seq $num $num); do
sum=$(($i   $sum))
done
echo "The sum of the previous numbers is $sum"

done 

CodePudding user response:

First you can use the following bash function:

sum() {
    local sum=0
    for arg in "$@"; do
        (( sum  = arg ))
    done   
    echo $sum
}

The second way is to do a non-looping variant:

{ printf %d  "$@"; echo 0; } | bc

Example

Put the above in a script file, sum.

#!/bin/bash

{ printf %d  "$@"; echo 0; } | bc

Run it like so:

$ ./sum 4
4
$ ./sum 4 4 5
13

For the third way I can recommend :

No need for bash, plain sh will do as well:

#! /bin/sh - 
IFS= ; echo "$(($*))"

$* in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS (or space if $IFS is unset or nothing if $IFS is empty). $((...)) is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)

If you need floating point support, that's where you'll need a different shell like ksh93 or zsh (not bash as bash only supports integer arithmetic), though you could also use awk:

#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t =ARGV[i]; print t}

That will use long (for integer) and double (for floating point) type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale). With some awk implementations, it will fail if the first number is negative as awk would try to interpret it as an option.

Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:

$ POSIXLY_CORRECT=1 ./sum  0xap3 0xa
90 # (0xa * 2^3)   0xa
$ awk --non-decimal-data -f ./sum  010
8

CodePudding user response:

seq $num $num shows the sequential numbers from $num to $num and is neither elegant nor correct here.

I'd write it like this:

#!/bin/bash
#accumulated sum of numbers

i=0
sum=0
while [[ true ]]; do

echo "Insert a number: "
read num

if (($num < 0)); then
echo "Negative number, exit..."
echo "The sum of the previous numbers is $sum"
break
else ((sum =$num))
fi
done

As every nerd I have my own bash scripting tutorial, see http://linuxintro.org/wiki/BaBE

  • Related