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.