Como posso usar o valor expandido de uma variável shell no nome de outra variável?

2

Estou morrendo de fome tentando fazer a seguinte coisa funcionar:

#!/bin/bash
MARCOMIN=1
MARCOMAX=3
ENZOMIN=1
ENZOMAX=3
GIOVANNIMIN=1
GIOVANNIMAX=3
VALUEMARCO=12
VALUEGIOVANNI=4
VALUEENZO=12

for i in MARCO ENZO GIOVANNI; do
        echo $$iMIN is $i\'s MIN
        echo $$iMAX is $i\'s MAX
        echo $VALUE$i is $i\'s VALUE
done

exit 0

Não escreve macro como eu gostaria, no entanto.

me@myhost:~$ bash test.sh
20341iMIN is MARCO's MIN
20341iMAX is MARCO's MAX
MARCO is MARCO's VALUE
20341iMIN is ENZO's MIN
20341iMAX is ENZO's MAX
ENZO is ENZO's VALUE
20341iMIN is GIOVANNI's MIN
20341iMAX is GIOVANNI's MAX
GIOVANNI is GIOVANNI's VALUE

Obviamente, este é apenas um dos meus testes. Eu tentei muitas maneiras diferentes de escrever macros dessa maneira, mas não consigo consertar. Encontrei muitas perguntas semelhantes aqui e no SO, mas nenhuma delas correspondeu ao meu caso.

bash -x test.sh segue:

+ MARCOMIN=1
+ MARCOMAX=3
+ ENZOMIN=1
+ ENZOMAX=3
+ GIOVANNIMIN=1
+ GIOVANNIMAX=3
+ VALUEMARCO=12
+ VALUEGIOVANNI=4
+ VALUEENZO=12
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'MARCO'\''s' MIN
21466iMIN is MARCO's MIN
+ echo 21466iMAX is 'MARCO'\''s' MAX
21466iMAX is MARCO's MAX
+ echo MARCO is 'MARCO'\''s' VALUE
MARCO is MARCO's VALUE
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'ENZO'\''s' MIN
21466iMIN is ENZO's MIN
+ echo 21466iMAX is 'ENZO'\''s' MAX
21466iMAX is ENZO's MAX
+ echo ENZO is 'ENZO'\''s' VALUE
ENZO is ENZO's VALUE
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'GIOVANNI'\''s' MIN
21466iMIN is GIOVANNI's MIN
+ echo 21466iMAX is 'GIOVANNI'\''s' MAX
21466iMAX is GIOVANNI's MAX
+ echo GIOVANNI is 'GIOVANNI'\''s' VALUE
GIOVANNI is GIOVANNI's VALUE
+ exit 0
    
por Marco 24.08.2017 / 21:25

2 respostas

3

Bash suporta variável indireta :

#!/bin/bash
MARCOMIN=1
MARCOMAX=3
ENZOMIN=1
ENZOMAX=3
GIOVANNIMIN=1
GIOVANNIMAX=3
VALUEMARCO=12
VALUEGIOVANNI=4
VALUEENZO=12

for i in MARCO ENZO GIOVANNI; do
    for j in MIN MAX VALUE; do
        varname="${i}${j}"
        # For VALUE we need reverse order of i and j
        [[ $j = VALUE ]] && varname="${j}${i}"

        printf "%d is %s's %s\n" "${!varname}" "$i" "$j"
    done
done

exit 0

Eu fiz um pouco mais com o laço interno e uso de printf no lugar de echo , mas a idéia central é que, dado um nome de variável foo armazenado em outra variável bar você pode obter o valor de $foo fazendo ${!bar} .

Mais: link

    
por 26.08.2017 / 12:00
-1

Usar uma expansão de variável dentro do nome de outra variável é tradicionalmente realizado com o comando eval builtin shell. Isso geralmente leva à síndrome do palito inclinado (muitas barras invertidas e escapes duplos), o que sugere que pode haver uma maneira "melhor" de realizar o que você deseja fazer. Há também problemas de segurança relacionados ao uso do eval builtin.

De qualquer forma, essa é uma maneira de realizar o que você deseja:

# ...
    eval echo \$${i}MIN is \$i\\'s MIN
    eval echo \$${i}MAX is \$i\\'s MAX
    eval echo \$VALUE${i} is \$i\\'s VALUE
# ...
    
por 24.08.2017 / 21:36