Εργασία με Arrays στο Linux Shell Scripting – Μέρος 8


Δεν μπορούμε να φανταστούμε μια γλώσσα προγραμματισμού χωρίς την έννοια των πινάκων. Δεν έχει σημασία πώς εφαρμόζονται σε διάφορες γλώσσες. Αντίθετα, οι πίνακες μας βοηθούν να ενοποιήσουμε δεδομένα, παρόμοια ή διαφορετικά, κάτω από ένα συμβολικό όνομα.

Εδώ, καθώς ανησυχούμε για το σενάριο φλοιού, αυτό το άρθρο θα σας βοηθήσει να παίξετε με ορισμένα σενάρια φλοιού που χρησιμοποιούν αυτήν την έννοια των συστοιχιών.

Αρχικοποίηση και χρήση πίνακα

Με νεότερες εκδόσεις του bash, υποστηρίζει μονοδιάστατους πίνακες. Ένας πίνακας μπορεί να δηλωθεί ρητά από το declare shell-builtin.

declare -a var  

Αλλά δεν είναι απαραίτητο να δηλώσετε μεταβλητές πίνακα όπως παραπάνω. Μπορούμε να εισαγάγουμε μεμονωμένα στοιχεία σε πίνακα απευθείας ως εξής.

var[XX]=<value>

όπου το «XX» υποδηλώνει τον δείκτη του πίνακα. Για την κατάργηση αναφοράς στοιχείων πίνακα χρησιμοποιήστε τη σύνταξη σγουρή αγκύλη, δηλ.

${var[XX]}

Σημείωση: Η ευρετηρίαση του πίνακα ξεκινά πάντα με 0.

Ένας άλλος βολικός τρόπος για να αρχικοποιήσετε ολόκληρο τον πίνακα είναι χρησιμοποιώντας το ζεύγος παρενθέσεων όπως φαίνεται παρακάτω.

var=( element1 element2 element3 . . . elementN )

Υπάρχει ακόμη ένας άλλος τρόπος εκχώρησης τιμών σε πίνακες. Αυτός ο τρόπος αρχικοποίησης είναι μια υποκατηγορία της μεθόδου που εξηγήθηκε προηγουμένως.

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

Μπορούμε επίσης να διαβάσουμε/να εκχωρήσουμε τιμές στον πίνακα κατά τη διάρκεια του χρόνου εκτέλεσης χρησιμοποιώντας το read shell-builtin.

read -a array

Τώρα κατά την εκτέλεση της παραπάνω δήλωσης μέσα σε ένα σενάριο, περιμένει κάποια είσοδο. Πρέπει να παρέχουμε τα στοιχεία του πίνακα διαχωρισμένα με κενό διάστημα (και όχι με επιστροφή μεταφοράς). Αφού εισαγάγετε τις τιμές, πατήστε enter για να τερματίσετε.

Για να διασχίσουμε τα στοιχεία του πίνακα μπορούμε επίσης να χρησιμοποιήσουμε για βρόχο.

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

Το παρακάτω σενάριο συνοψίζει τα περιεχόμενα αυτής της συγκεκριμένης ενότητας.

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

Διάφορες Λειτουργίες σε Πίνακες

Πολλές από τις τυπικές λειτουργίες συμβολοσειράς λειτουργούν σε πίνακες. Κοιτάξτε το παρακάτω δείγμα δέσμης ενεργειών που υλοποιεί ορισμένες λειτουργίες σε πίνακες (συμπεριλαμβανομένων πράξεων συμβολοσειράς).

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

Ακολουθεί η έξοδος που παράγεται κατά την εκτέλεση του παραπάνω σεναρίου.

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

Νομίζω ότι δεν έχει σημασία να εξηγήσουμε λεπτομερώς το παραπάνω σενάριο καθώς είναι αυτονόητο. Αν χρειαστεί θα αφιερώσω ένα μέρος αυτής της σειράς αποκλειστικά στους χειρισμούς χορδών.

Αντικατάσταση εντολών με πίνακες

Η αντικατάσταση εντολών εκχωρεί την έξοδο μιας εντολής ή πολλαπλών εντολών σε άλλο περιβάλλον. Εδώ σε αυτό το πλαίσιο πινάκων μπορούμε να εισάγουμε την έξοδο των εντολών ως μεμονωμένα στοιχεία πινάκων. Η σύνταξη έχει ως εξής.

array=( $(command) )

Από προεπιλογή, τα περιεχόμενα στην έξοδο της εντολής που χωρίζονται με λευκά κενά είναι συνδεδεμένα στον πίνακα ως μεμονωμένα στοιχεία. Το ακόλουθο σενάριο παραθέτει τα περιεχόμενα ενός καταλόγου, τα οποία είναι αρχεία με 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

Προσομοίωση Δισδιάστατων Πίνακες

Μπορούμε εύκολα να αναπαραστήσουμε έναν δισδιάστατο πίνακα χρησιμοποιώντας έναν μονοδιάστατο πίνακα. Σε σειρά μείζονος σειράς τα στοιχεία αναπαράστασης σε κάθε σειρά ενός πίνακα αποθηκεύονται προοδευτικά σε ευρετήρια πίνακα με διαδοχικό τρόπο. Για έναν πίνακα mXn, ο τύπος για τον ίδιο μπορεί να γραφτεί ως.

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

Κοιτάξτε ένα άλλο δείγμα σεναρίου για την προσθήκη 2 πινάκων και την εκτύπωση του προκύπτοντος πίνακα.

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

Παρόλο που υπάρχουν περιορισμοί για την υλοποίηση πινάκων μέσα σε δέσμες ενεργειών φλοιού, γίνεται χρήσιμο σε μερικές περιπτώσεις, ειδικά όταν χειριζόμαστε την αντικατάσταση εντολών. Από διοικητική άποψη, η έννοια των συστοιχιών άνοιξε το δρόμο για την ανάπτυξη πολλών σεναρίων παρασκηνίου σε συστήματα GNU/Linux.