Trabalhando com Arrays em Linux Shell Scripting – Parte 8
Não podemos imaginar uma linguagem de programação sem o conceito de arrays. Não importa como eles são implementados entre os vários idiomas. Em vez disso, os arrays nos ajudam a consolidar dados, semelhantes ou diferentes, sob um nome simbólico.
Aqui, como estamos preocupados com scripts de shell, este artigo irá ajudá-lo a brincar com alguns scripts de shell que fazem uso desse conceito de arrays.
Inicialização e uso do array
Com versões mais recentes do bash, ele suporta matrizes unidimensionais. Um array pode ser declarado explicitamente pelo shell embutido declare.
declare -a var
Mas não é necessário declarar variáveis de array como acima. Podemos inserir elementos individuais no array diretamente da seguinte maneira.
var[XX]=<value>
onde 'XX' denota o índice da matriz. Para desreferenciar elementos da matriz, use a sintaxe de colchetes, ou seja,
${var[XX]}
Nota: a indexação de array sempre começa com 0.
Outra maneira conveniente de inicializar um array inteiro é usar o par de parênteses conforme mostrado abaixo.
var=( element1 element2 element3 . . . elementN )
Existe ainda outra maneira de atribuir valores a arrays. Esta forma de inicialização é uma subcategoria do método explicado anteriormente.
array=( [XX]=<value> [XX]=<value> . . . )
Também podemos ler/atribuir valores ao array durante o tempo de execução usando o shell embutido read.
read -a array
Agora, ao executar a instrução acima dentro de um script, ele aguarda alguma entrada. Precisamos fornecer os elementos do array separados por espaço (e não por retorno de carro). Após inserir os valores pressione enter para finalizar.
Para percorrer os elementos do array, também podemos usar o loop for.
for i in “${array[@]}”
do
#access each element as $i. . .
done
O script a seguir resume o conteúdo desta seção específica.
#!/bin/bash
array1[0]=one
array1[1]=1
echo ${array1[0]}
echo ${array1[1]}
array2=( one two three )
echo ${array2[0]}
echo ${array2[2]}
array3=( [9]=nine [11]=11 )
echo ${array3[9]}
echo ${array3[11]}
read -a array4
for i in "${array4[@]}"
do
echo $i
done
exit 0
Várias operações em arrays
Muitas das operações de string padrão funcionam em arrays. Veja o exemplo de script a seguir que implementa algumas operações em arrays (incluindo operações de string).
#!/bin/bash
array=( apple bat cat dog elephant frog )
#print first element
echo ${array[0]}
echo ${array:0}
#display all elements
echo ${array[@]}
echo ${array[@]:0}
#display all elements except first one
echo ${array[@]:1}
#display elements in a range
echo ${array[@]:1:4}
#length of first element
echo ${#array[0]}
echo ${#array}
#number of elements
echo ${#array[*]}
echo ${#array[@]}
#replacing substring
echo ${array[@]//a/A}
exit 0
A seguir está a saída produzida na execução do script acima.
apple
apple
apple bat cat dog elephant frog
apple bat cat dog elephant frog
bat cat dog elephant frog
bat cat dog elephant
5
5
6
6
Apple bAt cAt dog elephAnt frog
Acho que não há significado em explicar detalhadamente o script acima, pois ele é autoexplicativo. Se necessário dedicarei uma parte desta série exclusivamente à manipulação de cordas.
Substituição de comandos com matrizes
A substituição de comando atribui a saída de um comando ou de vários comandos a outro contexto. Aqui neste contexto de arrays podemos inserir a saída de comandos como elementos individuais de arrays. A sintaxe é a seguinte.
array=( $(command) )
Por padrão, o conteúdo da saída do comando separado por espaços em branco é inserido no array como elementos individuais. O script a seguir lista o conteúdo de um diretório, que são arquivos com permissões 755.
#!/bin/bash
ERR=27
EXT=0
if [ $# -ne 1 ]; then
echo "Usage: $0 <path>"
exit $ERR
fi
if [ ! -d $1 ]; then
echo "Directory $1 doesn't exists"
exit $ERR
fi
temp=( $(find $1 -maxdepth 1 -type f) )
for i in "${temp[@]}"
do
perm=$(ls -l $i)
if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then
echo ${i##*/}
fi
done
exit $EXT
Simulando matrizes bidimensionais
Podemos facilmente representar uma matriz bidimensional usando uma matriz unidimensional. Na representação de ordem principal da linha, os elementos de representação em cada linha de uma matriz são armazenados progressivamente em índices de array de maneira sequencial. Para uma matriz mXn, a fórmula para a mesma pode ser escrita como.
matrix[i][j]=array[n*i+j]
Veja outro exemplo de script para adicionar 2 matrizes e imprimir a matriz resultante.
#!/bin/bash
read -p "Enter the matrix order [mxn] : " t
m=${t:0:1}
n=${t:2:1}
echo "Enter the elements for first matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read x[$(($n*$i+$j))]
done
done
echo "Enter the elements for second matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read y[$(($n*$i+$j))]
z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]}))
done
done
echo "Matrix after addition is"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
echo -ne "${z[$(($n*$i+$j))]}\t"
done
echo -e "\n"
done
exit 0
Embora existam limitações para implementar arrays dentro de scripts de shell, ele se torna útil em algumas situações, especialmente quando lidamos com substituição de comandos. Do ponto de vista administrativo, o conceito de arrays abriu caminho para o desenvolvimento de muitos scripts de segundo plano em sistemas GNU/Linux.