2

Is there a way to call a variable through the $i in a while loop? To access a specific variable automatically?

This is a scaled down version of what i'm trying to do:

i=1;

while [ $i -lt 4 ]; do
    let card$i=1;
    let i++;
done

let i=1;

while [[ $i -lt 4 ]]; do

    if [ "$card$i" = "1" ]; then 
        let card$i++;
    fi

    let i++;
done

Is there a way to make this work?

(I'm trying to do this with +50 variables. This is just scaled down)

Thanks.

2
  • You are looking for indirect expansion. Commented Sep 1, 2016 at 7:00
  • Not sure what you mean, that you want to increment 50 variables every loop? If so you can use indirect expansion although i would suggest saving yourself possible trouble down the line and just using an array. Commented Sep 1, 2016 at 7:00

1 Answer 1

1

Use a nameref variable (supported starting from Bash 4.3):

A variable can be assigned the nameref attribute using the -n option to the declare or local builtin commands to create a nameref, or a reference to another variable. This allows variables to be manipulated indirectly. Whenever the nameref variable is referenced or assigned to, the operation is actually performed on the variable specified by the nameref variable's value. A nameref is commonly used within shell functions to refer to a variable whose name is passed as an argument to the function. For instance, if a variable name is passed to a shell function as its first argument, running

declare -n ref=$1

inside the function creates a nameref variable ref whose value is the variable name passed as the first argument. References and assignments to ref are treated as references and assignments to the variable whose name was passed as $1. If the control variable in a for loop has the nameref attribute, the list of words can be a list of shell variables, and a name reference will be established for each word in the list, in turn, when the loop is executed. Array variables cannot be given the -n attribute. However, nameref variables can reference array variables and subscripted array variables. Namerefs can be unset using the -n option to the unset builtin. Otherwise, if unset is executed with the name of a nameref variable as an argument, the variable referenced by the nameref variable will be unset.

Thus you can make your code work as follows:

i=1;

while [ $i -lt 4 ]; do
    let card$i=1;
    let i++;
done

let i=1;

while [[ $i -lt 4 ]]; do

    declare -n cardref=card$i
    if [ "$cardref" = "1" ]; then 
        let cardref++;
    fi

    let i++;
done

For bash versions before 4.3 you can do the following:

i=1;

while [ $i -lt 4 ]; do
    let card$i=1;
    let i++;
done

let i=1;

while [[ $i -lt 4 ]]; do

    cardref=card$i
    if [ "${!cardref}" = "1" ]; then 
        let $cardref++;
    fi

    let i++;
done
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer i really appreciate it! but when i run it i get this: "./test: line 14: declare: -n: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...]"
@andr8076 Which version of bash do you use?
"version 3.2.57(1)-release" ;)
@andr8076 I added to my answer the solution for older versions of bash.
WOW that is amazing! Thank you very much!

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.