Cria dinamicamente array no bash com variáveis como nome do array

2

Isso foi perguntado várias vezes, mas nenhum dos métodos funciona. Gostaria de criar dinamicamente matrizes com nomes de matriz retirados das variáveis. Então, vamos começar com apenas um array por enquanto:

#!/bin/bash
i="aaa"
eval ${i}=("1")

resulta em

./1.sh: line 3: syntax error near unexpected token '('
./1.sh: line 3: 'eval ${i}=("1")'

mesmo resultado com:

$(eval ${i})=('1')
$(eval echo ${i})=('1')
$(eval "echo ${i}")=('1')

Eu não quero avaliar tudo, apenas o nome da matriz. Se for possível eu gostaria de evitar usar eval em tudo

    
por meso_2600 29.04.2015 / 10:58

3 respostas

5

eval espera uma string como o argumento. Você não pode usar ( sem aspas, tem um significado especial no shell.

i=aaa
eval "$i=(1 2)"  # Use a string, $i will expand in double quotes.
echo ${aaa[1]})

Você também pode usar declare ou typeset em vez de eval :

declare -a $i='(1 2)'

Você ainda precisa citar os parênteses e espaços.

Para evitar eval completamente, você pode atribuir um por um:

#! /bin/bash
name=aaa
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
    read "$name[$i]" <<< "${values[i]}"
done
echo ${aaa[1]})
    
por 29.04.2015 / 11:10
0

Aqui está uma maneira de carregar o array sem usar eval . Ele não usa o ( data ) construct - em vez disso, ele usa uma string de entrada com a sua escolha de delimitador - o exemplo usa |

i=aaa
IFS='|' read -a "$i" <<<"1|2   with spaces"
printf '%s\n' "${aaa[@]}"

Saída:

1
2   with spaces
    
por 29.04.2015 / 16:09
0

Você pode usar declare com nomes e valores dinâmicos e indireção de variáveis para fazer referência a variáveis com base em seus nomes. printf '%q' pode ajudá-lo a "escapar da shell" valores para que eles possam ser usados durante as atribuições dinâmicas.

#!/bin/bash
declare -a products=( phone computer )
printf 'Product: %s\n' "${products[@]}"
# Product: phone
# Product: computer
unset products

declare varName='products'
declare -a "${varName}"='( cell\ phone laptop\ computer )'
declare arrayRef="${varName}[@]"
printf 'Product: %s\n' "${!arrayRef}"
# Product: cell phone
# Product: laptop computer
unset "${varName}"

declare -a toCopy=( 'LED TV' '"Smart" car' )
declare -a "${varName}"="( $( printf '%q ' "${toCopy[@]}" ) )"
printf 'Product: %s\n' "${!arrayRef}"
# Product: LED TV
# Product: "Smart" car
unset "${varName}"
    
por 30.10.2015 / 02:30

Tags