Pesquisa de site

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.