Se você estiver trabalhando com uma grande quantidade de dados em seus scripts Bash, os arrays tornarão sua vida muito mais fácil. Algumas pessoas ficam intimidadas com a sintaxe. Mas uma vez aprendido, tornará seus scripts mais poderosos, com menos variáveis para pensar.
Declarando uma matriz
Matrizes no Bash permitem armazenar vários dados em uma única variável, como uma lista Python. Isso os torna ferramentas poderosas para gerenciar conjuntos de valores relacionados, como nomes de arquivos, nomes de usuários, opções de configuração ou argumentos de linha de comando.
Ao contrário de muitas outras linguagens de programação, o Bash não exige que você declare explicitamente um tipo de array. Você simplesmente atribui valores usando uma sintaxe específica e o Bash sabe que é um array. O método de declaração varia dependendo do tipo de array (abordado posteriormente).
Para declarar um array indexado, que é o tipo mais comum de array, basta digitar o nome, um sinal de igual e parênteses.
arr=()
É isso. Você acabou de declarar um array vazio. Você pode ver seus elementos usando o comando echo, assim:
echo $arr
Como não há elementos, você não verá nada além de uma linha em branco. Você pode atribuir valores ao array na mesma linha. Para fazer isso, digite elementos separados por espaço entre parênteses.
fruits=("apple" "banana" "cherry")Cada valor separado por espaço torna-se um elemento da matriz. Você pode verificar isso com:
echo "${fruits[@]}"Você também pode declarar um array vazio e adicionar elementos posteriormente.
fruits=()
fruits+=("apple")
fruits+=("banana" "cherry")
Imprimir o array exibirá os elementos recém-adicionados.
Essa abordagem é útil se você precisar preencher o array dinamicamente. Você também pode atribuir elementos individuais por índice.
fruits[0]="apple"
fruits[1]="banana"
fruits[2]="cherry"
Outra maneira de declarar um array é usando o declare integrado para definir explicitamente uma matriz indexada.
declare -a colors=("red" "green" "blue")Isso deixa claro para os outros que ‘colors’ pretende ser um array, o que pode ser útil em scripts maiores. Para confirmar se uma variável Bash é um array (e de que tipo), use o declare -p comando.
Isto é particularmente útil ao depurar scripts.
Loop através de um array
Depois de declarar um array, você normalmente desejará fazer algo com seus elementos: imprimi-los, processá-los ou passá-los para comandos. No Bash, existem várias maneiras de percorrer arrays, e compreender essas abordagens é fundamental para escrever scripts flexíveis e sem erros.
A maneira mais comum de iterar cada elemento em um array é com um simples loop for Bash.
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
echo "I like $fruit"
doneIsso é ótimo para analisar os valores. Mas e se você precisar dos índices também? Para isso, você pode usar um loop for estilo C, como este:
for ((i=0; i<${#fruits[@]}; i++)); do
echo "Fruit #$i is ${fruits[$i]}"
doneIsso é ideal se você precisar de posição e valor. Para obter apenas os índices, você pode usar a expansão especial ${!array[@]}assim:
for index in "${!fruits[@]}"; do
echo "Index $index = ${fruits[$index]}"
done Esta técnica também é útil quando o array não é sequencial (por exemplo, se alguns elementos foram removidos). Se o seu array vier da saída de um comando, um while read loop pode ser mais eficiente ou mais limpo.
printf '%sn' "${lines[@]}" | while read -r file; do
echo "Processing $file"
doneEssa abordagem é excelente ao ler dados dinamicamente de comandos ou arquivos. Outro truque legal é que você pode percorrer vários arrays juntos. Aqui está um exemplo:
names=("Alice" "Bob" "Charlie")
ages=(25 30 35)
for ((i=0; i echo "${names[$i]} is ${ages[$i]} years old"
doneAo fazer o loop de vários arrays, sempre certifique-se de que eles tenham o mesmo comprimento.
Diferentes tipos de arrays no Bash
Os arrays Bash vêm em algumas variedades e compreender suas diferenças ajuda você a escolher a ferramenta certa para o seu script. Bash oferece suporte a dois tipos principais de array:
- Matrizes indexadas: listas padrão indexadas por números.
- Matrizes associativas: pares chave-valor indexados por strings.
Há também um tipo especial digno de nota chamado arrays esparsos, onde os índices numéricos não são sequenciais. Vamos examinar cada tipo.
Matrizes indexadas
Matrizes indexadas são o tipo mais comum, perfeitas quando você deseja armazenar listas ordenadas, como nomes de arquivos, IDs de usuários ou números. Cada elemento é identificado por um índice inteiro começando em 0.
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}"
echo "${fruits[1]}"Você pode visualizar todos os elementos de uma vez ou verificar o número de elementos:
echo "${fruits[@]}"
echo "${#fruits[@]}"Matrizes indexadas são úteis quando você tem uma lista com ordem natural ou deseja iterar pelos resultados dos comandos.
Matrizes associativas
Matrizes associativas atuam como dicionários ou mapas hash em muitas outras linguagens. Eles permitem atribuir valores a chaves de string em vez de índices numéricos.
declare -A capitals=(
[France]="Paris"
[Italy]="Rome"
[Japan]="Tokyo"
)
echo "${capitals[France]}"
Você pode percorrê-los facilmente:
for country in "${!capitals[@]}"; do
echo "$country → ${capitals[$country]}"
doneObserve que a ordem das chaves nas matrizes associativas é indefinida. Se a ordem for importante, você precisará classificá-los manualmente. Matrizes associativas são úteis quando você precisa mapear relacionamentos ou manipular dados no formato JSON.
Matrizes esparsas
Matrizes esparsas são um recurso menos conhecido, mas interessante. Eles são matrizes indexadas com lacunas na numeração. Você pode atribuir elementos a índices arbitrários. Bash não exige que eles sejam sequenciais.
numbers=()
numbers[2]=200
numbers[10]=1000
numbers[42]=4200
echo "${!numbers[@]}"
Acessar índices não definidos não retornará nada:
echo "${numbers[5]}"Você ainda pode percorrer os elementos existentes com segurança. Se você tiver um grande conjunto de dados onde nem todos os índices são usados, ou estiver trabalhando com resultados que naturalmente possuem “buracos”, então o recurso esparso pode muitas vezes ser útil.
Acessando, modificando e excluindo elementos de array
Depois de declarar e preencher um array, a próxima etapa é aprender como extrair valores, atualizá-los e removê-los quando necessário. Trabalhar com elementos de array no Bash é simples, mas existem alguns comportamentos sutis que vale a pena lembrar.
Você pode acessar um elemento por seu índice (para matrizes indexadas) ou chave (para matrizes associativas). Para matrizes indexadas:
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}"
echo "${fruits[2]}"Para matrizes associativas:
declare -A capitals=(
[France]="Paris"
[Italy]="Rome"
[Japan]="Tokyo"
)
echo "${capitals[Japan]}"
Em ambos os casos, se o índice ou chave não tiver um valor, você obterá uma string vazia como saída. Se você quiser acessar todos os elementos ou índices de uma vez, existem algumas sintaxes especiais. Aqui está uma folha de dicas que você pode seguir.
Sintaxe de Expansão | Descrição |
|---|---|
${matriz[@]} | Todos os valores |
${!matriz[@]} | Todos os índices ou chaves |
${#matriz[@]} | Número de elementos |
${matriz[*]} | Todos os valores (mesclados em uma string) |
Sempre cite suas expansões: "${array[@]}". Expansões sem aspas podem falhar quando os elementos contêm espaços ou curingas.
Para modificar um elemento do array, basta reatribuí-lo:
fruits[1]="blackberry"
echo "${fruits[1]}"
fruits[1]="blueberry"
echo "${fruits[1]}"
Você também pode anexar novos elementos:
fruits+=("dragonfruit")Para matrizes associativas, você reatribui valores às chaves.
capitals["France"]="Paris"
echo "${capitals[France]}"
capitals["France"]="Marseille"
echo "${capitals[France]}"
A reatribuição de um valor substitui o antigo, portanto, tenha cuidado ao executá-lo.
Para excluir um elemento, você pode usar o unset comando. Ele pode remover elementos específicos ou todo o array.
unset 'fruits[1]'
echo "${fruits[@]}"
Para remover vários elementos:
unset 'fruits[0]' 'fruits[2]'
Para deletar todo o array, basta passar o nome do array:
unset fruits
O mesmo vale para matrizes associativas. Use o comando unset e a chave (em vez do índice) para remover esse elemento.
unset 'capitals[France]'
Se você deseja modificar ou remover vários valores, usar um loop for para iterar pela matriz é uma boa ideia.
Alguns truques avançados de array
Agora você já sabe como declarar, percorrer e manipular arrays. No entanto, o Bash pode fazer muito mais com eles. Vejamos algumas técnicas avançadas de array que podem tornar seus scripts mais inteligentes e fáceis de manter.
Fatiar
Você pode extrair subconjuntos de matrizes usando a sintaxe de fatia.
${array[@]:start:length}Aqui, início se refere ao primeiro elemento da fatia, enquanto comprimento se refere a quantos elementos você deseja manter no subconjunto. Observe que os arrays Bash têm indexação baseada em 0. Exemplo:
numbers=(10 20 30 40 50)
echo "${numbers[@]:1:3}"
Temos os três elementos do meio, já que cortamos a partir do índice um. Isto é útil quando você deseja processar uma parte dos resultados de um comando.
Copiando e combinando
Copiar um array requer simplesmente que você atribua os elementos do array a outro novo array.
copy=("${fruits[@]}")Bash copia arrays por valor, não por referência. Portanto, modificar a ‘cópia’ não afetará o original.
Para mesclar dois ou mais arrays em um, você passa seus elementos para um novo array usando a sintaxe de expansão.
numbers=(1 2 3)
more_numbers=(4 5 6)
combined=("${numbers[@]}" "${more_numbers[@]}")
echo "${combined[@]}"
Classificando
Classificar um array significa reorganizá-lo em uma ordem específica. Isso pode ser numericamente ou alfabeticamente (dependendo do tipo de elemento), crescente ou decrescente. O Bash não possui uma função de classificação integrada, mas é fácil de conseguir com a substituição de comandos e o comando de classificação.
fruits=("banana" "apple" "cherry" "date")
IFS=$'n' sorted=($(sort unset IFS
echo "${sorted[@]}"Aqui, o comando sort classifica os elementos em ordem alfabética. IFS=$'n' garante que os elementos que contêm espaços não sejam divididos incorretamente. Armazenamos a saída classificada em um novo array.
Da mesma forma, também podemos fazer a classificação reversa.
IFS=$'n' sorted=($(sort -r unset IFS
No caso de dados numéricos, você pode usar sort -n.
numbers=(42 5 19 100 3)
IFS=$'n' sorted_nums=($(sort -n unset IFS
echo "${sorted_nums[@]}"
Removendo duplicatas
Um problema clássico. Remova quaisquer itens duplicados na matriz para que todos os elementos restantes sejam únicos. Podemos obter ajuda do comando sort novamente.
numbers=(1 2 2 3 4 3 5)
unique=($(printf "%sn" "${numbers[@]}" | sort -u))
echo "${unique[@]}"
Essa abordagem funciona imprimindo todos os elementos, classificando-os e removendo duplicatas com -u. No entanto, este método depende da ordem. Ele classifica sua matriz no processo. Se precisar manter a ordem original, você terá que fazer um loop e rastrear os elementos vistos manualmente.
Filtrando matrizes
O último truque que gostaria de abordar é filtrar elementos de um array. Faremos isso usando correspondência de padrões e expansão de parâmetros.
files=("data.txt" "image.png" "notes.txt" "script.sh")
txt_files=()
for f in "${files[@]}"; do
[[ $f == *.txt ]] && txt_files+=("$f")
done
echo "${txt_files[@]}"Esse truque é simples, mas poderoso ao lidar com listas de arquivos ou conjuntos de dados mistos.
Com isso, você deve ter uma boa noção de como usar arrays no Bash para manipular seus dados. Isso o ajudará a escrever scripts melhores. Você pode começar examinando alguns exemplos de scripts Bash.