Εργασία με 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.