Το Bash παρέχει δύο τύπους παραμέτρων: "βαθμωτές" τιμές και πίνακες. Μια βαθμωτή τιμή μπορεί να είναι μια συμβολοσειρά ή ένας αριθμός· αντιπροσωπεύει ένα μόνο "πράγμα".
Τις περισσότερες φορές, οι βαθμωτές τιμές αρκούν για να περιέχουν τα δεδομένα σου. Μερικές φορές όμως χρειάζεται να αποθηκεύσεις μια λίστα από βαθμωτές τιμές. Σε αυτή την περίπτωση θα χρησιμοποιήσεις έναν πίνακα.
Υπάρχουν δύο είδη πινάκων:
Τα πρώτα κεφάλαια αυτού του κειμένου καλύπτουν τους πίνακες με αριθμητικές θέσεις (στο εξής απλώς "πίνακες"). Λεπτομέρειες για τους συσχετιστικούς πίνακες εμφανίζονται στο τέλος.
Οι πίνακες του Bash μπορούν να αποθηκεύσουν μόνο βαθμωτές τιμές. Δεν υπάρχει η δυνατότητα δημιουργίας διδιάστατου πίνακα (πίνακα από πίνακες).
Μπορείς να αρχικοποιήσεις έναν πίνακα αναθέτοντας σε μια μεταβλητή μια λίστα στοιχείων μέσα σε παρενθέσεις (πιθανώς κενή).
myarray=("one" "two" "three")
Όπως συμβαίνει με κάθε ανάθεση μεταβλητής, δεν πρέπει να υπάρχουν κενά γύρω από το σύμβολο ίσον.
Πρόσεξε ότι δεν υπάρχουν κόμματά ανάμεσα στα στοιχεία· είναι μια λίστα από συμβολοσειρές χωρισμένες με κενά διαστήματα.
Στην πραγματικότητα, το πόσα κενά διαστήματα υπάρχουν μέσα στις παρενθέσεις είναι εντελώς αυθαίρετο. Οι αλλαγές γραμμής επιτρέπονται· χρησιμοποίησε όσες θέλεις για να βελτιώσεις την αναγνωσιμότητα.
myarray=(
"first element"
"second element"
"this is the last element"
)
Αναθέτοντας μια λίστα συμβολοσειρών σε μια μεταβλητή πίνακα με αυτόν τον τρόπο, η πρώτη συμβολοσειρά αποθηκεύεται στη θέση μηδέν, η επόμενη στη θέση ένα, η επόμενη στη θέση δύο και ούτω καθεξής.
Μπορείς να αρχικοποιήσεις έναν "αραιό πίνακα" ορίζοντας τις θέσεις που χρειάζεσαι.
raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Για να το επαναλάβουμε: οι θέσεις των πινάκων ξεκινούν από το μηδέν. Αυτό το απόσπασμα κώδικα τυπώνει "true":
myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false
Μπορείς να χρησιμοποιήσεις την εντολή declare (ή local μέσα σε μια συνάρτηση) για να ορίσεις ότι μια μεταβλητή θα περιέχει έναν πίνακα.
declare -a myarray
Είναι πιο ιδιωματικό να αναθέσεις απλώς μια λίστα σε παρενθέσεις (ίσως κενή) για να αρχικοποιήσεις τη μεταβλητή.
Όπως είδες στο σημείωση παραπάνω, η σύνταξη για να έχεις πρόσβαση σε ένα στοιχείο πίνακα είναι ${myarray[$index]}.
Η θέση δίνεται μέσα σε αγκύλες.
Τα άγκιστρα είναι υποχρεωτικά.
Για τους πίνακες με αριθμητικές θέσεις, η θέση είναι μια αριθμητική παράσταση. Το εγχειρίδιο του Bash αναφέρει:
Μέσα σε μια αριθμητική παράσταση, οι μεταβλητές του shell μπορούν επίσης να αναφέρονται με το όνομά τους, χωρίς τη σύνταξη επέκτασης παραμέτρων.
Αυτό σημαίνει ότι το $ δεν είναι απαραίτητο για την "απλή" επέκταση μεταβλητής.
Μπορείς να έχεις πρόσβαση στα στοιχεία έτσι, που είναι λίγο πιο ευανάγνωστο:
i=5
echo "${myarray[i]}"
# ..............^
Αν η θέση που δίνεις δεν υπάρχει στον πίνακα, το αποτέλεσμα της επέκτασης είναι μια κενή συμβολοσειρά.
Για να αναθέσεις σε ένα συγκεκριμένο στοιχείο του πίνακα, χρησιμοποίησε αυτή τη σύνταξη:
myarray[10]="hello"
Για να προσθέσεις στοιχεία στο τέλος ενός πίνακα, χρησιμοποίησε τον τελεστή συνένωσης και ανάθεσης += και βάλε παρενθέσεις:
myarray+=("new element 1" "new element 2")
Συνήθως θα χρειαστεί να κάνεις επανάληψη πάνω στις τιμές ενός πίνακα.
Χρησιμοποίησε έναν βρόχο for (που τον είδες στην ενότητα Επανάληψη):
myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
echo "$value"
done
Πρόσεξε την ειδική σύνταξη για την επέκταση του πίνακα: "${myarray[@]}"
Αυτή η μορφή επέκτασης παραμέτρων αντικαθιστά τις τιμές του πίνακα ως ξεχωριστές λέξεις.
Είναι κατά κάποιο τρόπο ισοδύναμη με:
for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"
Η μορφή "${myarray[@]}" λειτουργεί με αραιούς πίνακες, επεκτεινόμενη μόνο στις τιμές που έχουν οριστεί.
Αυτή η ειδική επέκταση, όπου ως θέση χρησιμοποιείται το σύμβολο @, είναι ειδική μόνο μέσα σε διπλά εισαγωγικά.
Ακολουθούν μερικά ακόμη κομμάτια ειδικής σύνταξης που τα χρειαζόμαστε για την επανάληψη πάνω σε έναν πίνακα. Περιγράφονται στο εγχειρίδιο, στην ενότητα Επέκταση παραμέτρων του shell.
Για να βρεις το μήκος ενός πίνακα, χρησιμοποίησε το ${#myarray[@]}, με ένα # πριν από το όνομα.
Το "μήκος" ενός πίνακα είναι ο αριθμός των στοιχείων του.
Για να πάρεις τη λίστα με τις θέσεις ενός πίνακα, χρησιμοποίησε το "${!myarray[@]}", με ένα ! πριν από το όνομα και την επέκταση μέσα σε διπλά εισαγωγικά.
Για τους πίνακες με αριθμητικές θέσεις, οι θέσεις επεκτείνονται σε αριθμητική σειρά.
Μερικές φορές χρειάζεσαι τη θέση μαζί με την τιμή. Υπάρχουν δύο τρόποι να το κάνεις.
Όταν ξέρεις ότι οι θέσεις σχηματίζουν μια αδιάκοπη ακολουθία, μπορείς να χρησιμοποιήσεις έναν αριθμητικό βρόχο for.
for ((i = 0; i < ${#myarray[@]}; i++)); do
echo "$i -> ${myarray[i]}"
done
Πρόσεξε τη σύνταξη ${#myarray[@]}, με τον χαρακτήρα # μπροστά από το όνομα του πίνακα.
Επειδή οι πίνακες αριθμούν τις θέσεις τους ξεκινώντας από το μηδέν, η τελευταία θέση του πίνακα είναι κατά ένα μικρότερη από το μήκος του.
Όταν ο πίνακας είναι αραιός, μπορείς να χρησιμοποιήσεις αυτή τη μορφή:
for index in "${!raindrops[@]}"; do
echo "$index -> ${raindrops[index]}"
done
Πρόσεξε τη σύνταξη ${!myarray[@]}, με τον χαρακτήρα ! μπροστά από το όνομα του πίνακα.
Αν θέλεις να δεις το περιεχόμενο ενός πίνακα, χρησιμοποίησε την εντολή declare με την επιλογή -p:
a=("the 'first' element"
second
third
'the "last" element')
declare -p a
Αυτό εμφανίζει το περιεχόμενο με την κανονική σύνταξη εισαγωγικών του shell.
declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")
Για να το επαναλάβουμε, οι συσχετιστικοί πίνακες χρησιμοποιούν συμβολοσειρές ως θέσεις, όχι αριθμούς. Όλα όσα γράψαμε παραπάνω ισχύουν και για τους συσχετιστικούς πίνακες, με μικρές διαφορές. Γενικά, χρησιμοποιούμε τον όρο "κλειδί" και όχι "θέση": οι συσχετιστικοί πίνακες αντιστοιχίζουν κλειδιά σε τιμές.
Σε αντίθεση με τους πίνακες, οι συσχετιστικοί πίνακες πρέπει να δηλώνονται.
Χρησιμοποίησε την επιλογή -A της declare (ή της local μέσα σε μια συνάρτηση):
declare -A mymap
myfunc() {
local -A my_local_map
# ...
}
Τα ζεύγη κλειδιού-τιμής ορίζονται μέσα στη λίστα με τις παρενθέσεις:
mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap
Αυτό εμφανίζει:
declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Να θυμάσαι ότι οι συσχετιστικοί πίνακες δεν έχουν σειρά.
Η δήλωση και η αρχικοποίηση μπορούν να γίνουν σε μία γραμμή.
declare -A mymap=([first]=foo [second]=bar [third]=baz)
Στις πρόσφατες εκδόσεις του Bash, η αρχικοποίηση μπορεί να χρησιμοποιήσει μια λίστα (key value key value ...).
declare -A mymap=(first foo second bar third baz)
Χρησιμοποιείται η ίδια σύνταξη όπως πριν για την πρόσβαση στα στοιχεία: ${mymap[$key]}.
Τα κλειδιά των συσχετιστικών πινάκων δεν αξιολογούνται σε αριθμητικό πλαίσιο. Απαιτείται η συνήθης σύνταξη επέκτασης παραμέτρων.
Η ανάθεση χρησιμοποιεί την ίδια σύνταξη όπως πριν:
mymap[$key]="$value"
Μπορείς να χρησιμοποιήσεις έναν βρόχο for value in "${mymap[@]}" για να κάνεις επανάληψη.
Ωστόσο, συνήθως θέλεις και το κλειδί μαζί με την τιμή.
Χρησιμοποίησε τη σύνταξη "${!mymap[@]}" που είδαμε παραπάνω.
for key in "${!mymap[@]}"; do
echo "$key -> ${mymap[$key]}"
done
Αυτό εμφανίζει
second -> bar
first -> foo
third -> baz
Για να το τονίσουμε ξανά, τα κλειδιά δεν έχουν καμία σειρά.