Treballar amb matrius a Linux Shell Scripting - Part 8


No podem imaginar un llenguatge de programació sense el concepte de matrius. No importa com s'implementen entre diferents idiomes. En canvi, les matrius ens ajuden a consolidar dades, semblants o diferents, sota un nom simbòlic.

Aquí, com que ens preocupen els scripts d'intèrpret d'ordres, aquest article us ajudarà a jugar amb alguns scripts d'intèrpret d'ordres que fan ús d'aquest concepte de matrius.

Inicialització i ús de la matriu

Amb les versions més noves de bash, admet matrius unidimensionals. Una matriu es pot declarar explícitament mitjançant l'intèrpret d'ordres integrat declare.

declare -a var  

Però no és necessari declarar variables de matriu com l'anterior. Podem inserir elements individuals a la matriu directament de la següent manera.

var[XX]=<value>

on XX denota l'índex de matriu. Per desreferenciar els elements de la matriu, utilitzeu la sintaxi de claudàtors, és a dir.

${var[XX]}

Nota: La indexació de matrius sempre comença amb 0.

Una altra manera convenient d'iniciar una matriu sencera és utilitzant el parèntesi com es mostra a continuació.

var=( element1 element2 element3 . . . elementN )

Hi ha una altra manera d'assignar valors a les matrius. Aquesta forma d'inicialització és una subcategoria del mètode explicat anteriorment.

array=( [XX]=<value> [XX]=<value> . . . )

També podem llegir/assignar valors a la matriu durant el temps d'execució utilitzant l'intèrpret d'ordres read.

read -a array

Ara, després d'executar la instrucció anterior dins d'un script, espera una entrada. Hem de proporcionar els elements de la matriu separats per espai (i no per retorn de carro). Després d'introduir els valors, premeu Intro per finalitzar.

Per recórrer els elements de la matriu també podem utilitzar for loop.

for i in “${array[@]}”
do
	#access each element as $i. . .
done 

El següent script resumeix el contingut d'aquesta secció concreta.

#!/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

Moltes de les operacions de cadena estàndard funcionen amb matrius. Mireu el següent script d'exemple que implementa algunes operacions en matrius (incloses les operacions de cadena).

#!/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 continuació es mostra la sortida produïda en executar l'script anterior.

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

Crec que no té cap importància explicar el guió anterior en detall, ja que s'explica per si mateix. Si cal, dedicaré una part d'aquesta sèrie exclusivament a manipulacions de cordes.

La substitució d'ordres assigna la sortida d'una ordre o diverses ordres a un altre context. Aquí, en aquest context de matrius, podem inserir la sortida de les ordres com a elements individuals de matrius. La sintaxi és la següent.

array=( $(command) )

Per defecte, els continguts de la sortida de l'ordre separats per espais en blanc es connecten a la matriu com a elements individuals. El següent script enumera el contingut d'un directori, que són fitxers amb 755 permisos.

#!/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

Podem representar fàcilment una matriu bidimensional mitjançant una matriu unidimensional. En ordre principal de fila, els elements de representació de cada fila d'una matriu s'emmagatzemen progressivament en índexs de matriu de manera seqüencial. Per a una matriu mXn, la fórmula per a la mateixa es pot escriure com.

matrix[i][j]=array[n*i+j]

Mireu un altre script de mostra per afegir 2 matrius i imprimir la matriu resultant.

#!/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 

Tot i que hi ha limitacions per implementar matrius dins dels scripts d'intèrpret d'ordres, esdevé útil en un bon grapat de situacions, especialment quan gestionem la substitució d'ordres. Des d'un punt de vista administratiu, el concepte de matrius va obrir el camí per al desenvolupament de molts scripts de fons en sistemes GNU/Linux.