Θα αναφερόμαστε στη γλώσσα ως AWK και στο εκτελέσιμο που διερμηνεύει προγράμματα AWK ως awk ή gawk.
Ένα πρόγραμμα AWK αποτελείται από ζεύγη μοτίβου-ενέργειας
pattern1 { action1 }
pattern2 { action2 }
...
Ένα μοτίβο μπορεί να είναι ένα μοτίβο κανονικής έκφρασης για αντιστοίχιση με την είσοδο. Μπορεί επίσης να είναι οποιαδήποτε έκφραση που έχει ως αποτέλεσμα μια τιμή αληθής/ψευδής.
Μια ενέργεια είναι μία ή περισσότερες εντολές AWK. Τα άγκιστρα που την περικλείουν είναι υποχρεωτικά.
Αν το αποτέλεσμα του μοτίβου είναι αληθές, τότε εκτελείται η αντίστοιχη ενέργεια.
Το AWK αναλύει την είσοδο σε μια σειρά από καταγραφές. Κάθε καταγραφή χωρίζεται σε μηδέν ή περισσότερα πεδία.
Η προεπιλεγμένη συμπεριφορά είναι να:
Το μοτίβο μπορεί να παραλειφθεί, οπότε η ενέργεια εκτελείται για κάθε καταγραφή εισόδου.
Η ενέργεια μπορεί να παραλειφθεί, οπότε η προεπιλεγμένη ενέργεια είναι να εκτυπωθεί η τρέχουσα καταγραφή.
Υπάρχουν δύο ειδικά μοτίβα που χρησιμοποιούνται συχνά.
BEGIN εκτελεί τη σχετική ενέργεια πριν καταναλωθεί οποιαδήποτε είσοδος.END εκτελεί τη σχετική ενέργεια αφού καταναλωθεί όλη η είσοδος.Αναφέρεσαι στα πεδία ως $1, $2, $3, κ.λπ.
Η τρέχουσα καταγραφή είναι το $0.
Ακολουθούν μερικές άλλες συχνά χρησιμοποιούμενες ενσωματωμένες μεταβλητές.
RS είναι το διαχωριστικό καταγραφών της εισόδου.
Όπως αναφέρθηκε, η προεπιλεγμένη τιμή του είναι ο χαρακτήρας αλλαγής γραμμής.FS είναι το διαχωριστικό πεδίων της εισόδου.Αυτές οι μεταβλητές ορίζονται συχνά στο μπλοκ ενέργειας BEGIN.
Αυτές οι μεταβλητές ορίζονται αυτόματα από το AWK κατά την εκτέλεση του προγράμματος.
NF αποθηκεύει τον αριθμό των πεδίων στην τρέχουσα καταγραφή.
$NF.NR αποθηκεύει τον τρέχοντα αριθμό καταγραφής.
NR κρατά τον συνολικό αριθμό καταγραφών που έχουν υποστεί επεξεργασία μέχρι στιγμής.FNR αποθηκεύει τον τρέχοντα αριθμό καταγραφής του τρέχοντος αρχείου εισόδου.
NR == FNR {action}
Αυτό σημαίνει "αν ο συσσωρευμένος αριθμός καταγραφών ισούται με τον αριθμό καταγραφών του τρέχοντος αρχείου."
Αυτό μπορεί να ισχύει μόνο για καταγραφές στο πρώτο αρχείο εισόδου.Το AWK χρησιμοποιεί την ίδια έννοια αλήθειας με τη C.
0 είναι ψευδής.Επειδή το AWK είναι μια γλώσσα επεξεργασίας κειμένου, οι τιμές αλήθειας επεκτείνονται και στις συμβολοσειρές.
"" είναι ψευδής.Τα σχόλια ξεκινούν με τον χαρακτήρα # και εκτείνονται μέχρι το τέλος της γραμμής.
Στα συστήματα τύπου Unix, το /etc/passwd περιέχει πληροφορίες για τους χρήστες.
Κάθε χρήστης περιγράφεται σε ξεχωριστή γραμμή, με τα πεδία να χωρίζονται με άνω και κάτω τελείες.
Για να εμφανίσεις τα ονόματα χρηστών:
awk '
BEGIN { FS = ":" }
{ print $1 }
' /etc/passwd
Παρατήρησε ότι η ενέργεια {print $1} δεν έχει μοτίβο, οπότε εκτελείται για κάθε καταγραφή.
Αν θέλουμε να περιορίσουμε την έξοδο μόνο στους χρήστες που χρησιμοποιούν το bash ως κέλυφος σύνδεσης, μπορούμε να κάνουμε το εξής:
awk '
BEGIN { FS = ":" }
$7 == "/bin/bash" { print $1 }
' /etc/passwd
Μια φορά κι έναν καιρό, υπήρχε μια πολύβουη πόλη που ονομαζόταν Cyberspace. Το Cyberspace ήταν μια ψηφιακή μητρόπολη, με εκατομμύρια κατοίκους να συνδέονται και να αποσυνδέονται κάθε μέρα. Για να παρακολουθεί όλους αυτούς τους χρήστες, το Cyberspace είχε ένα ειδικό αρχείο που ονομαζόταν /etc/passwd.
Το αρχείο /etc/passwd ήταν σαν τηλεφωνικός κατάλογος για την πόλη. Κατέγραφε κάθε χρήστη που είχε λογαριασμό στο σύστημα, μαζί με μερικές σημαντικές πληροφορίες για τον καθένα:
| n | πεδίο |
|---|---|
| 1 | όνομα χρήστη |
| 2 | κωδικός πρόσβασης (το "x" δείχνει ότι ο πραγματικός κωδικός πρόσβασης είναι αποθηκευμένος αλλού, για λόγους ασφάλειας) |
| 3 | UID, ένα μοναδικό αριθμητικό αναγνωριστικό χρήστη |
| 4 | GID, ένα μοναδικό αριθμητικό αναγνωριστικό ομάδας (συνήθως ίδιο με το UID) |
| 5 | πληροφορίες χρήστη (συνήθως το πλήρες όνομα του χρήστη, αλλά μπορεί να περιλαμβάνουν και άλλες πληροφορίες) |
| 6 | κατάλογος home |
| 7 | κέλυφος σύνδεσης |
Τα πεδία χωρίζονται με τον χαρακτήρα άνω τελεία. Αυτή είναι μια τυπική καταχώριση:
glennj:x:1010:1010:Glenn Jackman:/home/glennj:/usr/local/bin/fish
Το αρχείο το διαχειριζόταν μια ομάδα διαχειριστών συστήματος, που ήταν υπεύθυνη για τη δημιουργία νέων λογαριασμών, την ενημέρωση των υπαρχόντων λογαριασμών και τη διαγραφή παλιών λογαριασμών. Οι διαχειριστές συστήματος ήταν οι φύλακες του Cyberspace, φροντίζοντας ώστε μόνο εξουσιοδοτημένοι χρήστες να μπορούν να έχουν πρόσβαση στο σύστημα.
Μια μέρα, ένας νέος διαχειριστής συστήματος, ο Alex, προσλήφθηκε για να μπει στην ομάδα. Ο Alex ανυπομονούσε να αναλάβει τη δουλειά και έμαθε γρήγορα όλα τα μυστικά του αρχείου /etc/passwd. Έμαθε πώς να προσθέτει νέους χρήστες στο σύστημα, πώς να ενημερώνει τις πληροφορίες των χρηστών και πώς να αφαιρεί παλιούς χρήστες.
Καθώς ο Alex δούλευε στο αρχείο /etc/passwd, παρατήρησε κάτι περίεργο. Μερικοί χρήστες είχαν περίεργους ή ασυνήθιστους καταλόγους home. Κάποιοι χρήστες είχαν τον κατάλογο home τους ορισμένο σε /dev/null, ενώ άλλοι τον είχαν ορισμένο σε περίεργες διαδρομές που δεν υπήρχαν.
Ο Alex κατάλαβε ότι αυτοί οι χρήστες δεν ήταν πραγματικοί άνθρωποι, αλλά ψεύτικοι λογαριασμοί που είχαν δημιουργηθεί από χάκερ. Οι χάκερ είχαν βρει τρόπο να εκμεταλλευτούν μια ευπάθεια του συστήματος και είχαν δημιουργήσει αυτούς τους ψεύτικους λογαριασμούς για να αποκτήσουν πρόσβαση στο Cyberspace.
Ο Alex ήξερε ότι έπρεπε να δράσει. Χρησιμοποίησε το awk για να αναλύσει το αρχείο /etc/passwd και έγραψε ένα σενάριο για να εντοπίσει όλους τους ψεύτικους λογαριασμούς. Στη συνέχεια συνεργάστηκε με την υπόλοιπη ομάδα για να αφαιρέσει αυτούς τους λογαριασμούς και να διορθώσει την ευπάθεια που είχε επιτρέψει στους χάκερ να τους δημιουργήσουν εξαρχής.
Χάρη στη χρήση του awk από τον Alex, η ομάδα μπόρεσε να εντοπίσει και να αφαιρέσει τους ψεύτικους λογαριασμούς και να κάνει το Cyberspace ένα ασφαλέστερο μέρος για όλους. Οι διαχειριστές συστήματος συνέχισαν να διαχειρίζονται το αρχείο /etc/passwd, κρατώντας το ενημερωμένο και ασφαλές, και διασφαλίζοντας ότι μόνο εξουσιοδοτημένοι χρήστες θα έχουν πρόσβαση στο σύστημα.
Τώρα είναι η σειρά σου να γίνεις διαχειριστής συστήματος σαν τον Alex.
Ορίστε λίγη επιπλέον σύνταξη της AWK που θα χρειαστείς για να λύσεις αυτή την άσκηση.
Οι τελεστές Boolean είναι παρόμοιοι με άλλες γλώσσες:
| πράξη | παράδειγμα |
|---|---|
| AND | expr1 && expr2 |
| OR | expr1 || expr2 |
| NOT | ! expr |
Η κλήση μιας συνάρτησης έχει οικεία σύνταξη:
function greet(name) {
print "Hello", name
}
BEGIN {
greet("Mary") # prints "Hello Mary"
}
Γράψε ένα πρόγραμμα awk που να εμφανίζει το πρώτο πεδίο, χωρισμένο με άνω τελεία, για κάθε γραμμή του αρχείου passwd.
Γράψε μια εντολή awk που εμφανίζει τον αριθμό γραμμής κάθε καταγραφής στο αρχείο εισόδου. Εμφάνισε μόνο τον αριθμό γραμμής, όχι άλλες πληροφορίες.
Στο Cyberspace, ένας "έγκυρος" κατάλογος home ξεκινά με /home ή /root.
Εμφάνισε τις καταγραφές του αρχείου εισόδου με μη έγκυρους καταλόγους home.
Εμφάνισε τις καταγραφές όπου ο κατάλογος home είναι έγκυρος και το κέλυφος σύνδεσης είναι bash.
Γράψου στο Exercism για να μάθεις και να κατακτήσεις AWK με 3 έννοιες92 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.