Nesta dica mostro um recurso do
Bash que poucos conhecem: a concatenação de strings e arranjos - conhecidos também como arrays ou vetores.
Eu sempre concatenei strings da seguinte forma:
Adicionando uma string no final de $string:
$ string="$string""nova_palavra"
E elementos no final de vetores:
$ vetor=( ${vetor[@]} $novo_elemento )
Mas, como vocês podem ver, estas são "gambiarras". Até funcionam, mas a gente fica com aquela impressão de que podia ser melhor. E realmente pode.
O segundo método, o do vetor, apresenta algumas falhas e inconsistências, principalmente quando há elementos que contém o caractere espaço " ".
Visando contornar este problema, passei a utilizar o seguinte método, já apresentado em outros textos meus aqui no VOL.
# Função que insere um novo elemento no final de um vetor
# Recebe como parâmetros:
# 1- O NOME do vetor que receberá o elemento
# 2- O valor a ser inserido
InsereFinalLista()
{
eval local Tamanho='${#'$1'[@]}'
eval $1\[$Tamanho\]="$2"
}
Ele recebe como parâmetro o NOME da variável que guarda o vetor, e em seguida o conteúdo a ser adicionado:
$ InsereFinalLista Vetor1 $Elemento
Mas, mesmo assim sentia que era uma solução "porca". Caramba, deve haver um jeito melhor de fazer isto!
Eis que, nas minhas fuçadas diárias e constantes no bash, utilizando aquela teoria dos
infinitos macacos (que uma hora ou outra escreveriam a obra completa de Shakespeare), digitei a seguinte instrução no terminal:
$ i+=1
E não deu erro!
Então pensei: "Mas baralho, isto que fiz não foi uma operação aritmética (incremento de 1), pois, para isso, ela deveria estar entre parênteses-duplos (( ))"
O que faço? Verifico o conteúdo da variável:
$ echo $i
1
Ué? O que é isso? Uma atribuição normal? Aperto a tecla "para cima" do teclado duas vezes e teclo Enter:
$ i+=1
E exibo novamente o conteúdo da variável:
$ echo $i
11
Ué? Como é que 1 virou 11? Será que este comando adiciona dez numa variável? O que acontece é que o caractere 1 é concatenado no final da variável i!
Faço então o seguinte teste:
$ for ((i=10,j=0;i<20;i++)); do j+=$i; done
Neste comando, a variável i é inicializada com 10 e j com 0. Em cada execução do laço, i é incrementado, e seu valor (como caractere) adicionado no final da variável j. O laço acaba quando i valer 19.
Exibindo j:
$ echo $j
010111213141516171819
Provado e aprovado!
Mas será que isto só funciona para variáveis comuns? Será que funciona para arranjos (arrays, listas, vetores)?
Mas é claro que sim!
Vejam o exemplo:
$ Vetor=( a b c "d á r i o")
Vejam que um elemento tem caracteres espaço.
E adiciono mais elementos no final do vetor:
$ Vetor+=( "a e i o u" consoante )
E exibo o conteúdo da variável:
$ echo ${Vetor[@]}
a b c d á r i o a e i o u consoante
Para ficar mais claro, vamos exibir elemento por elemento:
$ for ((j=0;j<${#Vetor[@]};j++)); do echo ${Vetor[$j]}; done
a
b
c
d á r i o
a e i o u
consoante
E é isto pessoal! Espero que estes recursos facilitem a vida dos "shelleiros" de plantão ;-)
Links interessantes: