Ar

Arrays em Bash

{one: "1 exercício", many: "%{count} de exercícios", other: "%{count} exercícios"}

Sobre Arrays

O Bash oferece dois tipos de parâmetros: valores "escalares" e arrays. Um valor escalar pode ser uma string ou um número; ele representa uma única "coisa".

Na maioria das vezes, valores escalares são suficientes para guardar seus dados. Mas, às vezes, você precisa armazenar uma lista de valores escalares. Nesse caso, você vai usar um array.

Existem dois tipos de arrays:

  • Arrays indexados numericamente associam uma chave inteira a um valor string. (Outras linguagens podem chamar isso de "lista" ou "sequência".)
  • Arrays associativos associam uma chave string a um valor string. (Outras linguagens podem chamar isso de "mapa" ou "dicionário".)

As primeiras seções deste documento abordam os arrays indexados numericamente (daqui em diante, chamados simplesmente de "arrays"). Os detalhes sobre arrays associativos aparecem no final.

Caution

Os arrays do Bash podem armazenar apenas valores escalares. Não há como criar um array bidimensional (array de arrays).

Declarando e inicializando uma variável de array

Você pode inicializar um array atribuindo uma lista de elementos entre parênteses (possivelmente vazia) a uma variável.

myarray=("one" "two" "three")

Como acontece com toda atribuição de variável, não pode haver espaços em volta do sinal de igual.

Repare que não há vírgulas separando os elementos; é uma lista de strings separadas por espaços em branco.

Na verdade, a quantidade de espaços em branco dentro dos parênteses é totalmente livre. Quebras de linha são permitidas; use quantas quiser para melhorar a legibilidade.

myarray=(
    "first element"
    "second element"
    "this is the last element"
)

Atribuir uma lista de strings a uma variável de array dessa forma guarda a primeira string no índice zero, a próxima string no índice um, a seguinte no índice dois, e assim por diante.

É possível inicializar um "array esparso" especificando os índices de que você precisa.

raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Note

Recapitulando: os índices de arrays começam em zero. Este trecho imprime "true":

myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false

Você pode usar o comando declare (ou local dentro de uma função) para indicar que uma variável vai conter um array.

declare -a myarray

É mais idiomático simplesmente atribuir uma lista entre parênteses (talvez vazia) para inicializar a variável.

Acessando elementos de um array

Como você viu na nota acima, a sintaxe para acessar um elemento de um array é ${myarray[$index]}. O índice é dado entre colchetes. As chaves são obrigatórias.

Note

Para arrays indexados numericamente, o índice é uma expressão aritmética. O manual do Bash afirma:

Dentro de uma expressão aritmética, variáveis do shell também podem ser referenciadas pelo nome, sem usar a sintaxe de expansão de parâmetros.

Isso significa que o $ não é necessário para a expansão "simples" de variáveis. Você pode acessar os elementos assim, o que é um pouco mais fácil de ler:

i=5
echo "${myarray[i]}"
# ..............^

Se o índice informado não existir no array, o resultado da expansão é uma string vazia.

Atribuindo valores a um array

Para atribuir a uma entrada específica do array, use esta sintaxe:

myarray[10]="hello"

Para acrescentar a um array, use o operador de atribuição concatenante += e use parênteses:

myarray+=("new element 1" "new element 2")

Iterando sobre um array

Normalmente você vai precisar iterar sobre os valores de um array. Use um laço for (que você viu no conceito Laço):

myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
    echo "$value"
done

Repare na sintaxe especial para expandir o array: "${myarray[@]}" Essa forma de expansão de parâmetros substitui os valores do array como palavras separadas. Ela é mais ou menos equivalente a:

for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"

A forma "${myarray[@]}" funciona com arrays esparsos, expandindo apenas os valores definidos.

Essa expansão especial, em que o índice é uma arroba (@), só é especial dentro de aspas duplas.

Outras expansões especiais de parâmetros

Aqui estão mais alguns detalhes de sintaxe especial de que precisamos para iterar sobre um array. Eles estão descritos no manual em Expansão de parâmetros do shell.

Para descobrir o comprimento de um array, use ${#myarray[@]}, com um # antes do nome. O "comprimento" de um array é o número de elementos nele.

Para extrair a lista de índices de um array, use "${!myarray[@]}", com um ! antes do nome e a expansão entre aspas duplas. Para arrays indexados numericamente, os índices são expandidos em ordem numérica.

Iterando sobre os índices de um array

Às vezes você precisa do índice além do valor. Há algumas formas de fazer isso.

  1. Quando você sabe que os índices formam uma sequência ininterrupta, pode usar um laço for aritmético.

    for ((i = 0; i < ${#myarray[@]}; i++)); do
        echo "$i -> ${myarray[i]}"
    done
    

    Repare na sintaxe ${#myarray[@]}, com o caractere # na frente do nome do array. Como os arrays começam no índice zero, o último índice do array é uma unidade menor que o comprimento do array.

  2. Quando o array é esparso, você pode usar esta forma:

    for index in "${!raindrops[@]}"; do
        echo "$index -> ${raindrops[index]}"
    done
    

    Repare na sintaxe ${!myarray[@]}, com o caractere ! na frente do nome do array.

Inspecionando um array

Se você quiser ver o conteúdo de um array, use o comando declare com a opção -p:

a=("the 'first' element"
   second
   third
   'the "last" element')
declare -p a

Isso imprime o conteúdo com as aspas no formato canônico do shell.

declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")

Arrays associativos

Recapitulando, arrays associativos usam strings como índices, não números. Tudo o que foi escrito acima vale para arrays associativos, mas com pequenas diferenças. Em geral, usamos o termo "chave" e não "índice": arrays associativos associam chaves a valores.

Declarando um array associativo

Diferentemente dos arrays, os arrays associativos precisam ser declarados. Use a opção -A do declare (ou de local dentro de uma função):

declare -A mymap

myfunc() {
    local -A my_local_map
    # ...
}

Inicializando um array associativo

Os pares chave-valor são especificados dentro da lista entre parênteses:

mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap

Isso imprime:

declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Note

Lembre-se de que os arrays associativos não têm ordem.

A declaração e a inicialização podem acontecer em uma única linha.

declare -A mymap=([first]=foo [second]=bar [third]=baz)

Em versões recentes do Bash, a inicialização pode usar uma lista (key value key value ...).

declare -A mymap=(first foo second bar third baz)

Acessando valores

A mesma sintaxe de antes é usada para acessar elementos: ${mymap[$key]}.

As chaves de arrays associativos não são avaliadas em contexto aritmético. É preciso usar a sintaxe usual de expansão de parâmetros.

Atribuindo a um array associativo

A atribuição usa a mesma sintaxe de antes:

mymap[$key]="$value"

Iterando

Você pode usar um laço for value in "${mymap[@]}" para iterar. No entanto, normalmente você também quer a chave junto com o valor.

Use a sintaxe "${!mymap[@]}" que vimos acima.

for key in "${!mymap[@]}"; do
    echo "$key -> ${mymap[$key]}"
done

Isso imprime

second -> bar
first -> foo
third -> baz

Vale reforçar: as chaves não têm ordem.

Editar via GitHub O link abre em uma nova janela ou aba