Bash scripting: O Associated Array reconhece apenas um valor quando diversos

2

Estas linhas de um script Bash (4.0)

klang=([string_0]='element_0' [string_1]='element_1' [string_2]='element_2')
echo "${klang[*]}"     # should output the all set elements
echo "${#klang[*]}"    # should output the number of set elements

retorna (por algum motivo):

element_2
1

Não há outros comandos definidos neste script e eu sou realmente novo no script Bash. O que aconteceu com os outros elementos ( Element_0 e Element_1 )? Isso realmente funcionou perfeitamente com matrizes indexadas e números e tudo, mas não funciona com texto - bem, exceto por um elemento que é um pouco menor do que eu pedia… Onde eu perdi alguma coisa?

    
por erch 12.01.2014 / 23:55

2 respostas

1

Se você não declarar a variável como uma matriz associativa, então

klang=([string_0]='element_0' [string_1]='element_1' [string_2]='element_2')

é tomado como uma atribuição de matriz normal (embora note que em matrizes bash e ksh93 , normal não são realmente normais arrays, eles são mais matrizes esparsas ou matrizes associativas com chaves limitadas a inteiros positivos).

Em bash , para um array normal , as chaves são avaliadas como expressões aritméticas. Como uma expressão aritmética, string_0 avalia o conteúdo de $string_0 e, se estiver vazio, para 0 . Então, o acima é provável que seja o mesmo que:

klang=([0]='element_0' [0]='element_1' [0]='element_2')

Então, é o mesmo que definir ${klang[0]} (que é igual a $klang ) 3 vezes.

Isso contrasta com ksh93 arrays (que bash copiou principalmente), em que a sintaxe a=([x]=y) é suportada apenas para matrizes associativas e cria automaticamente uma matriz associativa quando usada.

zsh matrizes associativas (que antecedem bash por décadas) são diferentes novamente. zsh normal arrays são arrays normais , zsh não suporta a sintaxe a=([x]=y) do bogus%. Em zsh , você precisa declarar matrizes associativas antes de defini-las e elas são definidas como:

normal_array=(val1 val2 val3)
typset -A associative_array
associative_array=(key1 val1 key2 val2)
associative_array+=(key3 val3...)

E $associative_array gasta para os valores não vazios como para matrizes normais (em ordem indefinida) e "$associative_array[@]}" para todos os valores como para matrizes normais . ${(k)associative_array} para as chaves não vazias , "${(k@)associative_arrays}" para todas as chaves , "${(kv@)associative_array}" para as chaves e valores, para que você possa imprimir o conteúdo de uma associação array com:

printf '%s => %s\n' "${(@kv)associative_array}"

Isso também significa que copiar uma matriz associativa é muito menos complicado do que com ksh93 / bash :

typeset -A B
B=("${(kv@)A}")

ao contrário de:

unset B
typeset -A B
for k in "${!A[@]}"; do B[$k]=${A[$k]}; done
    
por 13.01.2014 / 14:05
6

Primeiro, você precisa declarar sua variável ( klang here) como uma matriz associativa com bash :

$ declare -A klang
$ klang=([string_0]='element_0' [string_1]='element_1' [string_2]='element_2')
$ echo "${klang[*]}"
element_2 element_0 element_1
$ echo "${#klang[*]}"
3

Matrizes associativas foram introduzidas com bash versão 4.0 .

Eles foram implementados pela primeira vez por ksh93 , com o qual esse problema não aparece.

    
por 13.01.2014 / 00:16

Tags