0

So far I have this script:

#!/bin/sh
echo type in some numbers:
read input

From here on I'm stuck. Let's say input=30790148. What I want to do is add all of those integers up to get 3+0+7+9+0+1+4+8=32. How can I accomplish this?

3

5 Answers 5

4

Another way not using external tools:

read -p "Type some number: " num
for((i=0;i<${#num};i++)); do ((sum+=${num:i:1})); done

echo "$sum"
Sign up to request clarification or add additional context in comments.

5 Comments

What is it doing: ${num:i:1}. Seems like a number splitter, shifting one decimal -1- to the right by adding one to each fixed position i
@Timo It is a syntax for substrings. It means "return 1 character starting at ith character". Since $num is a "string", ${num:i:1} is bash's equivalent of num[i] in other languages.
Why not use $i here: ((sum+=${num:i:1}))
It's not mandatory to use $ in the arithmetic expansion (( expr )). From manual: ...shell variables may also be referenced by name without using the parameter expansion syntax.
ok, Using ((sum+=${num:i})) without 1 will be a right shift by one reducing the array to the right.
3

There are two core utilities, fold and paste, which you can use here (illustrated for input=12345):

fold -w1 <<< $input | paste -sd+ - | bc
  • fold -w1 wraps the input line to a width of 1 character:

    $ fold -w1 <<< $input
    1
    2
    3
    4
    5
    
  • paste -sd+ - merges the input sequentially (-s), i.e., into a single line, with a + delimiter (-d+), reading from standard input (the final -; optional for GNU paste):

    $ fold -w1 <<< $input | paste -sd+ -
    1+2+3+4+5
    
  • bc then calculates the sum:

    $ fold -w1 <<< $input | paste -sd+ - | bc
    15
    

Comments

1

This one using sed and bc

echo "12345" | sed -e 's/\(.\)/\1\+0/g' | bc

It's a bit hackish though since the +0 is not intuitive

Edit: Using & from @PaulHodges' answer, this would shorten to:

echo "12345" | sed 's/./&+0/g' | bc

4 Comments

This works fine with bc, but watch out with prepending zeroes to numbers; in some places, the number will suddenly be interpreted as octal.
Yeah, it's really abusing the fact that bc will interpret everything here as decimal. I was gunning for the shortest code possible e.g. sed 's/./&+0/g' | bc
I can't think of anything right now, but imagine a tool that got fed 1+02+09+0. Since 09 is not a valid octal number, it would definitely error out.
Sorry, figured out what you meant and deleted my comment, lol
0

This awk one-liner may help you:

awk '{for(i=1;i<=NF;i++)s+=$i}END{print s}' FS="" <<< yourString

for example:

kent$  awk '{for(i=1;i<=NF;i++)s+=$i}END{print s}' FS=""<<< "123456789" 
45     

Comments

0

With sed and bc -

input=30790148; echo $input | sed 's/[0-9]/&+/g; s/$/0/;' | bc

If you don't have GNU sed you might need to line break the commands instead of using a semicolon.

input=30790148;
echo $input | 
  sed '
     s/[0-9]/&+/g
      s/$/0/
  ' | bc

3 Comments

Hey, we can merge our answers and simplify it further sed 's/./&+0/g' | bc. TIL of &, thank you.
c.f. the comments on your answer - add the 0 separately at the end.
Yep, I was only trying to make it as short as possible. Anyway, thanks for &, another tool in the toolbox.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.