Arbeide med matriser i Linux Shell Scripting – Del 8
Vi kan ikke forestille oss et programmeringsspråk uten konseptet arrays. Det spiller ingen rolle hvordan de implementeres på forskjellige språk. I stedet hjelper matriser oss med å konsolidere data, like eller forskjellige, under ett symbolsk navn.
Her som vi er bekymret for shell scripting, vil denne artikkelen hjelpe deg med å leke med noen shell scripts som bruker dette konseptet med arrays.
Array-initialisering og bruk
Med nyere versjoner av bash støtter den endimensjonale arrays. En matrise kan eksplisitt deklareres av declare shell-builtin.
declare -a var
Men det er ikke nødvendig å deklarere matrisevariabler som ovenfor. Vi kan sette inn individuelle elementer til array direkte som følger.
var[XX]=<value>
der 'XX' angir matriseindeksen. For å dereferere matriseelementer bruk krøllete parentes-syntaksen, dvs.
${var[XX]}
Merk: Array-indeksering starter alltid med 0.
En annen praktisk måte å initialisere en hel matrise på er ved å bruke parantesene som vist nedenfor.
var=( element1 element2 element3 . . . elementN )
Det er enda en måte å tilordne verdier til matriser på. Denne måten å initialisere på er en underkategori av den tidligere forklarte metoden.
array=( [XX]=<value> [XX]=<value> . . . )
Vi kan også lese/tildele verdier til array i løpet av utførelsestiden ved å bruke read shell-builtin.
read -a array
Når den nå utfører setningen ovenfor i et skript, venter den på litt input. Vi må gi array-elementene atskilt med mellomrom (og ikke vognretur). Etter å ha lagt inn verdiene, trykk enter for å avslutte.
For å krysse gjennom array-elementene kan vi også bruke for loop.
for i in “${array[@]}”
do
#access each element as $i. . .
done
Følgende skript oppsummerer innholdet i denne spesielle delen.
#!/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
Ulike operasjoner på matriser
Mange av standard strengoperasjoner fungerer på matriser. Se på følgende eksempelskript som implementerer noen operasjoner på arrays (inkludert strengoperasjoner).
#!/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
Følgende er utdataene som ble produsert ved utføring av skriptet ovenfor.
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
Jeg tror det ikke er noen betydning å forklare manuset ovenfor i detalj, da det er selvforklarende. Om nødvendig vil jeg dedikere en del i denne serien utelukkende til strengmanipulasjoner.
Kommandoerstatning med matriser
Kommandoerstatning tildeler utdata fra en kommando eller flere kommandoer til en annen kontekst. Her i denne sammenhengen med arrays kan vi sette inn utdataene til kommandoer som individuelle elementer i arrays. Syntaksen er som følger.
array=( $(command) )
Som standard er innholdet i utdataene til kommandoen atskilt med mellomrom koblet til array som individuelle elementer. Følgende skript viser innholdet i en katalog, som er filer med 755 tillatelser.
#!/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
Simulering av todimensjonale matriser
Vi kan enkelt representere en 2-dimensjonal matrise ved å bruke en 1-dimensjonal matrise. I rad hovedrekkefølge blir representasjonselementer i hver rad i en matrise gradvis lagret i matriseindekser på en sekvensiell måte. For en mXn-matrise kan formel for det samme skrives som.
matrix[i][j]=array[n*i+j]
Se på et annet eksempelskript for å legge til 2 matriser og skrive ut den resulterende matrisen.
#!/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
Selv om det er begrensninger for implementering av arrays i shell-scripting, blir det nyttig i en håndfull situasjoner, spesielt når vi håndterer kommandoerstatning. Sett fra et administrativt synspunkt banet konseptet med arrays vei for utvikling av mange bakgrunnsskript i GNU/Linux-systemer.