Ricerca nel sito web

Lavorare con gli array nello scripting della shell Linux – Parte 8


Non possiamo immaginare un linguaggio di programmazione senza il concetto di array. Non importa come vengono implementati tra le varie lingue. Invece gli array ci aiutano a consolidare dati, simili o diversi, sotto un unico nome simbolico.

Poiché siamo preoccupati per lo scripting di shell, questo articolo ti aiuterà a giocare con alcuni script di shell che fanno uso di questo concetto di array.

Inizializzazione e utilizzo degli array

Con le versioni più recenti di bash, supporta array unidimensionali. Un array può essere dichiarato esplicitamente dalla shell incorporata declare.


declare -a var  

Ma non è necessario dichiarare variabili di array come sopra. Possiamo inserire singoli elementi nell'array direttamente come segue.


var[XX]=<value>

dove "XX" indica l'indice dell'array. Per dereferenziare gli elementi dell'array utilizzare la sintassi delle parentesi graffe, ad es.


${var[XX]}

Nota: l'indicizzazione degli array inizia sempre con 0.

Un altro modo conveniente per inizializzare un intero array è utilizzare la coppia di parentesi come mostrato di seguito.


var=( element1 element2 element3 . . . elementN )

Esiste ancora un altro modo per assegnare valori agli array. Questo modo di inizializzazione è una sottocategoria del metodo spiegato in precedenza.


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

Possiamo anche leggere/assegnare valori all'array durante l'esecuzione utilizzando la shell integrata read.


read -a array

Ora, dopo aver eseguito l'istruzione precedente all'interno di uno script, attende qualche input. Dobbiamo fornire gli elementi dell'array separati da spazio (e non ritorno a capo). Dopo aver inserito i valori premere Invio per terminare.

Per attraversare gli elementi dell'array possiamo anche usare il ciclo for.


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

Lo script seguente riassume il contenuto di questa particolare sezione.


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

Varie operazioni sugli array

Molte delle operazioni standard sulle stringhe funzionano sugli array. Guarda il seguente script di esempio che implementa alcune operazioni sugli array (incluse le operazioni sulle stringhe).


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

Di seguito è riportato l'output prodotto durante l'esecuzione dello script precedente.


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

Penso che non abbia alcun significato spiegare in dettaglio lo script di cui sopra poiché è autoesplicativo. Se necessario dedicherò una parte di questa serie esclusivamente alle manipolazioni delle corde.

Sostituzione dei comandi con array

La sostituzione dei comandi assegna l'output di uno o più comandi in un altro contesto. Qui in questo contesto di array possiamo inserire l'output dei comandi come singoli elementi di array. La sintassi è la seguente.


array=( $(command) )

Per impostazione predefinita, i contenuti nell'output del comando separati da spazi bianchi vengono inseriti nell'array come singoli elementi. Lo script seguente elenca il contenuto di una directory, ovvero file con permessi 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

Simulazione di array bidimensionali

Possiamo facilmente rappresentare una matrice bidimensionale utilizzando un array monodimensionale. Nell'ordine maggiore delle righe gli elementi di rappresentazione in ciascuna riga di una matrice vengono progressivamente memorizzati negli indici di array in modo sequenziale. Per una matrice mXn, la formula per la stessa può essere scritta come.


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

Guarda un altro script di esempio per aggiungere 2 matrici e stampare la matrice risultante.


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

Anche se ci sono limitazioni per l'implementazione degli array all'interno degli script di shell, diventa utile in una manciata di situazioni, specialmente quando gestiamo la sostituzione dei comandi. Da un punto di vista amministrativo, il concetto di array ha aperto la strada allo sviluppo di molti script in background nei sistemi GNU/Linux.