Eu quero o valor echo em a1, a2, a3. Mas meu código está imprimindo apenas a1, a2 e a3 não o valor armazenado dentro deles

1
a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1)); do
     echo $a$i
done 

Eu já tentei seguir

  1. echo ${a$i}
  2. echo $((ai))
  3. echo ${a}${i}
  4. c=$(echo a$i)

Mas nenhum deu a resposta certa.

    
por Vishal Choudhury 19.06.2017 / 16:22

4 respostas

4

Essa sintaxe ((i=1;i<=3;i=i+1)) é ksh93 (agora também é suportada por bash e zsh (embora você precise de espaços em branco entre for e (( em zsh )).

Em ksh93 e nas versões recentes de bash (4.3, 2014 ou acima), você pode fazer:

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    typeset -n name="a$i"
    printf '%s\n' "$name"
done 

Em zsh , você pode usar a sintaxe indireta de variável: ${(e)code} (desde maio de 1996), ${(P)name} (desde 1999)

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    name=a$i
    printf '%s\n' "${(P)name}"
    # or
    code="\$a$i"
    printf '%s\n' "${(e)code}"
    # or combined:
    printf '%s\n' "${(e):-\$a$i}" "${(P)${:-a$i}}"
done 

bash também adicionou seu próprio recurso de indireto de variável, mas usando uma sintaxe diferente (em 2.0 em dezembro de 1996), e uma que significa quase o oposto da do ksh93:

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    name=a$i
    printf '%s\n' "${!name}"
done 

Com qualquer shell POSIX, (incluindo mas não limitado a ksh93, bash ou zsh), você sempre pode fazer:

a1="one"
a2="two"
a3="three"
i=1; while [ "$i" -le 3 ]; do
    name=a$i
    eval "value=\${$name}"
    printf '%s\n' "$value"
    i=$((i + 1))
done 
    
por 19.06.2017 / 17:49
3

No bash, se você tem uma variável contendo o nome da variável que você quer, você pode usar indiretamente para acessá-la:

a1="one"
a2="two"
a3="three"
for((i=1;i<=3;i=i+1));do
    name="a$i"
    printf '%s\n' "${!name}"
done 

se você usar ${...} para expandir um parâmetro e o primeiro caractere for ! , o restante será tratado como o nome do parâmetro que contém o nome do parâmetro que você deseja acessar.

    
por 19.06.2017 / 16:37
2

Se você estiver usando o Bash, a maneira mais fácil de realizar a mesma coisa é usar uma matriz:

a[1]="one"
a[2]="two"
a[3]="three"

for ((i=1; i<=3; i=i+1)); do
    echo "${a[$i]}"
done

Você também pode percorrer o array:

for value in "${a[@]}"; do
     echo "$value"
done
    
por 19.06.2017 / 16:38
0

Se alguém precisar seguir esse caminho, em bash os seguintes trabalhos. A ideia é usar eval :

#!/bin/bash

a1="one"
a2="two"
a3="three"

for ((i=1;i<=3;i=i+1)); do
  var="a${i}"
  eval out=\$${var}
  echo $out
done

Saída:

one
two
three

A abordagem eval permite obter o valor de uma variável referenciada. Então, uma vez que temos o próprio nome da variável (acima, em var como "a $ {i}", que será a1, a2, etc), então é possível obter o valor da variável através do eval construído em.

Há alguma discussão aqui: Qual é o comando "eval"? no bash?

    
por 19.06.2017 / 16:32