0

Hi I am trying to update a variable that has a variable in it's name and can not figure out how:

n=6
tot=5
        let abc6xyz="$abc6xyz"+"$tot"
        let abc6xyz="$abc6xyz"+"$tot"
        echo "abc6xyz $abc6xyz"
#  Works fine
        let abc${n}xyz="$abc${n}xyz"+"$tot"
        echo "abc6xyz $abc6xyz"


++ n=6
++ tot=5
++ let abc6xyz=+5
++ let abc6xyz=5+5
++ echo 'abc6xyz 10'
abc6xyz 10
++ let abc6xyz=6xyz+5
./calc_tots.tst: line 9: let: abc6xyz=6xyz: value too great for base (error token is "6xyz")`enter code here`
++ echo 'abc6xyz 10'
abc6xyz 10

Thank you for your help in advance.

1 Answer 1

2

You have a couple of things working against you. First, avoid the use of let, it is an antiquated shell feature. Instead use POSIX arithmetic ((...)).

Next, $abc${n}xyz is expanded as $abc (which isn't defined) and ${n}xyz which is "6xyz" and isn't decimal, octal or hex so it is a number too great for base.

Using POSIX arithmetic in bash, you could change your script, incorporating ((...)) as:

#!/bin/bash

n=6
tot=5

    abc6xyz="$tot"
    ((abc6xyz+=tot))        ## use arithmetic operators ((..))
    echo "abc6xyz $abc6xyz"

    ((abc${n}xyz+=tot))           ## then use indirection, e.g. ${!foo}
    echo "abc6xyz $abc6xyz"

Example Use/Output

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15

Adding Indirection or final=$((...))

In the comments you explain you wish to take the number to include as n= as the first argument (positional parameter) to your script. In that case to access the total value after all of your additions, either use indirection or assign the final result of $((...)).

For example, using indirection:

#!/bin/bash

((abc${1}xyz+=5))
((abc${1}xyz+=5))

foo="abc${1}xyz"

echo "abc${1}xyz: ${!foo}"

Example Use/Output

$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10

Or preferably just assign the result of the last arithmetic operation, e.g.

#!/bin/bash

((abc${1}xyz+=5))
final=$((abc${1}xyz+=5))

echo "abc${1}xyz: $final"

Example Use/Output

$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10
Sign up to request clarification or add additional context in comments.

14 Comments

Yes, that will work, or just use ((abc${1}xyz+=tot)) instead.
OK, don't add to my answer, the comments are fine.
Yes but the comments get strung together as 1 line:
I am receiving a bad substitution with both tries ((abc${n}xyz+=tot)) echo "abc${n}xyz ${!abc${n}xyz}" ./tot.tst: line 8: abc${n}xyz ${!abc${n}xyz}: bad substitution
OK, I see the comments, please don't edit the answer. Don't use indirection here ${!abc${n}xyz}, that is a bad substitution. If you need indirection, it is somevar="abc${n}xyz" and then access with ${!somevar}, but the variable abcNxyz must exist. Please add (do not replace) your current version at the end of your original question so I can be sure I'm addressing your current problem.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.