Custom script output in unix

Viewed 52

There is a question to add the arguments from the script CLI and then display in the following format:

10 + 20 + 30 = 60

If the input is:

$ sum_for 10 20 30

The script that i have written is:

#!/bin/bash
sum=0
for i in $@;
  do 
    sum=$((sum+i)); 
  done


echo $sum
exit 0

Which just outputs the sum, instead as stated above. Can you please help me how to print the output as stated above.

3 Answers

You can just construct the output string on the fly, with something like:

#!/bin/bash

((sum = 0))                      # I like spacing expressions :-)
text=""                          # Initial text
prefix=""                        #   and term prefix.
for i in "$@" ; do               # Handle each term
    ((sum = sum + i))            #   by accumulating
    text="${text}${prefix}${i}"  #   and adding to expression.
    prefix=" + "                 # Adjust term prefix to suit.
  done

echo "${text} = ${sum}"          # Output expression and result.

This can be seen in action thusly:

pax> ./sum_for 5 6 72
5 + 6 + 72 = 83

And, if you wanted to make it relatively robust to bad input data, you could try:

#!/bin/bash

((sum = 0))
text=""
prefix=""
for i in "$@" ; do
    if [[ $i =~ ^-?[0-9]+$ ]] ; then
        ((sum = sum + i))
        text="${text}${prefix}${i}"
        prefix=" + "
    else
        echo "WARNING, ignoring non-integer '${i}'."
    fi
done

echo "${text} = ${sum}"

Showing a sample run of that with various invalid data items:

pax> ./some_for 5 6 72 x 6x x6 -3 +4 --4 ++7 -+3 +-4 "" + - 4
WARNING, ignoring non-integer 'x'.
WARNING, ignoring non-integer '6x'.
WARNING, ignoring non-integer 'x6'.
WARNING, ignoring non-integer '+4'.
WARNING, ignoring non-integer '--4'.
WARNING, ignoring non-integer '++7'.
WARNING, ignoring non-integer '-+3'.
WARNING, ignoring non-integer '+-4'.
WARNING, ignoring non-integer ''.
WARNING, ignoring non-integer '+'.
WARNING, ignoring non-integer '-'.
5 + 6 + 72 + -3 + 4 = 84

That disallows some values that you may wish to allow but I've opted for only numbers in their simplest form, like 4 instead of +4, or --4, or even ++++----+--+4 :-)

Changing what's permitted is a (relatively) simple matter of changing the regular expression filter.

You can pass all the shell arguments ,as a variable in awk and get the sum for all of them in its BEGIN section.

cat code.sh
var="$@"
awk -v value="$var" 'BEGIN{z=split(value,a," ");for(i=1;i<=z;i++){s+=a[i]};print s}'

Using printf you can do something like

#!/bin/bash

sum=0
for ((i=1; i <= $#; i++))
do
    ((sum += ${!i}))                                  # sum with indirection
    printf '%*.*s%d' 0 $(( i==1 ? 0 : 3)) ' + ' ${!i} # use variable width
done

printf ' = %d\n' $sum
Related