AWK

Από τη Βικιπαίδεια, την ελεύθερη εγκυκλοπαίδεια
Μετάβαση σε: πλοήγηση, αναζήτηση

Το AWK είναι εργαλείο ανάλυσης δεδομένων και παραγωγής αναφορών και χρησιμοποιεί μια γλώσσα σεναρίων που λειτουργεί με βάση τα δεδομένα εισόδου (data-driven), η οποία αποτελείται από ενέργειες που πρέπει να εκτελεστούν σε δεδομένα τύπου κειμένου (σε αρχεία ή ροές δεδομένων), με σκοπό την παραγωγή αναφορών με κάποια μορφοποίηση. Η γλώσσα που χρησιμοποιείται από το εργαλείο awk χρησιμοποιεί κυρίως τύπους δεδομένων συμβολοσειρών (strings), συσχετιστικών πινάκων (associative arrays, πίνακες των οποίων οι δείκτες είναι τύπου συμβολοσειράς) και κανονικές εκφράσεις (regular expressions).

Η γλώσσα AWK αποτέλεσε ένα από τα πρώτα εργαλεία που εμφανίστηκαν στην Έκδοση 7 του Unix (Version 7 Unix) και έγινε δημοφιλής σαν τρόπος να εισαχθούν υπολογιστικές λειτουργίες σε μια σωλήνωση του (pipeline) του Unix. Σχεδόν κάθε σύγχρονο λειτουργικό σύστημα τύπου Unix που είναι διαθέσιμο σήμερα περιλαμβάνει τη γλώσσα AWK. Η AWK αναφέρεται στο Single UNIX Specification σαν υποχρεωτικό εργαλείο ενός λειτουργικού συστήματος Unix και αποτελεί μαζί με το κέλυφος Bourne τις δύο μοναδικές γλώσσες σεναρίων που είναι κανονικά διαθέσιμες σε ένα περιβάλλον Unix.[1] Ανήκει επίσης στις εντολές που απαιτούνται από την προδιαγραφή Linux Standard Base.[2] Υπάρχουν επίσης διαθέσιμες υλοποιήσεις της AWK για πολλά άλλα λειτουργικά συστήματα.

Η AWK δημιουργήθηκε στα Bell Labs στα τέλη της δεκαετίας του 1970,[3] και το όνομά της προέρχεται από τα επίθετα των δημιουργών της — Alfred Aho, Peter Weinberger και Brian Kernighan. Το awk με μικρά γράμματα αναφέρεται στο αντίστοιχο πρόγραμμα του Unix ή του Plan 9 που εκτελεί προγράμματα γραμμένα στη γλώσσα AWK.

Η ισχύς, η συντομία, αλλά και οι περιορισμοί των πρώτων προγραμμάτων σε AWK ενέπνευσαν το Larry Wall να γράψει την Perl, ενώ ταυτόχρονα αναπτυσσόταν μια νέα, ισχυρότερη POSIX AWK και η gawk (GNU AWK). Αν και η AWK και ο sed είχαν σχεδιαστεί να υποστηρίζουν προγράμματα της μιας γραμμής, ακόμα και οι πρώτοι χρήστες της AWK από τα Bell Labs συχνά έγραφαν καλά δομημένα προγράμματα μεγάλου μεγέθους σε AWK. Παρά τον περιορισμένο σκοπό για τον οποίο προορίζεται, η AWK είναι Τιούρινγκ-πλήρης (Turing-complete).[4]

Δομή των προγραμμάτων σε AWK[Επεξεργασία | επεξεργασία κώδικα]

Κατά τον Alfred V. Aho:[5]

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

Ένα πρόγραμμα σε AWK είναι μια σειρά από ζεύγη πρότυπο-ενέργεια, που γράφονται ως εξής:

συνθήκη { ενέργεια }

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

Εκτός από απλές εκφράσεις της AWK, όπως η foo == 1 ή η /^foo/, η συνθήκη μπορεί να είναι BEGIN ή END, που έχουν σαν αποτέλεσμα η ενέργεια να εκτελείται πριν ή μετά από το διάβασμα όλων των εγγραφών, ή πρότυπο1, πρότυπο2 που ταιριάζει με το εύρος των εγγραφών που αρχίζουν με μια εγγραφή που ταιριάζει με το πρότυπο1 μέχρι και την εγγραφή που ταιριάζει με το πρότυπο2, πριν συνεχίσει πάλι την αναζήτηση για την επόμενη γραμμή που ταιριάζει με το πρότυπο1.

Οι εκφράσεις της AWK μπορούν να έχουν αριθμητικούς και λογικούς τελεστές, καθώς και τον τελεστή ~, που δοκιμάζει να ταιριάξει μια κανονική έκφραση σε μια συμβολοσειρά. Υπάρχει επίσης η βολική σύνταξη /regexp/, η οποία δοκιμάζει να ταιριάξει με την τρέχουσα εγγραφή χωρίς τη χρήση του τελεστή ~.

Εντολές της AWK[Επεξεργασία | επεξεργασία κώδικα]

Οι εντολές της AWK εισάγονται στη θέση της ενέργειας που αναφέρθηκε παραπάνω. Οι εντολές της AWK μπορούν να είναι κλήσεις συναρτήσεων, αναθέσεις μεταβλητών, υπολογισμοί, ή οποιοσδήποτε συνδυασμός αυτών. Η AWK περιλαμβάνει υποστήριξη για πολλές συναρτήσεις, ενώ διάφορες εκδόσεις της προσθέτουν επιπλέον συναρτήσεις, καθώς επίσης και δυναμικά συνδεδεμένες βιβλιοθήκες (dynamically linked libraries), οι οποίες προσφέρουν ακόμα περισσότερες συναρτήσεις.

Για συντομία στα παρακάτω παραδείγματα θα παραλείπονται οι αγκύλες ( { } ) που περιέχουν τις εντολές.

Η εντολή εκτύπωσης (print)[Επεξεργασία | επεξεργασία κώδικα]

Η εντολή print χρησιμοποιείται για την εμφάνιση κειμένου. Το κείμενο εξόδου τερματίζεται πάντα με μια προκαθορισμένη συμβολοσειρά που ονομάζεται διαχωριστής εγγραφών εξόδου (output record separator ή ORS) και εξορισμού είναι ο χαρακτήρας αλλαγής γραμμής. Η απλούστερη μορφή της εντολής είναι:

print
Εμφανίζει τα περιεχόμενα της τρέχουσας εγγραφής. Οι εγγραφές στην AWK χωρίζονται σε πεδία (fields), τα οποία μπορούν να εμφανιστούν ξεχωριστά:
print $1
Εμφανίζει το πρώτο πεδίο της τρέχουσας εγγραφής.
print $1, $3
Εμφανίζει το πρώτο και το τρίτο πεδίο της τρέχουσας εγγραφής και ανάμεσά τους εμφανίζει την προκαθορισμένη συμβολοσειρά που ονομάζεται διαχωριστής πεδίων εξόδου (output field separator ή OFS), η οποία εξορισμού είναι ο χαρακτήρας του κενού.

Αν και τα πεδία ($X) μοιάζουν με μεταβλητές (το σύμβολο $ σημαίνει μεταβλητή στην perl), στην πραγματικότητα αναφέρονται σε πεδία της τρέχουσας εγγραφής. Σαν ειδική περίπτωση, το $0 αναφέρεται σε ολόκληρη την εγγραφή. Επομένως οι εντολές "print" και "print $0" είναι ισοδύναμες.

Η εντολή print μπορεί επίσης να εμφανίσει τα αποτελέσματα υπολογισμών ή κλήσεων συναρτήσεων:

print 3+2
print foobar(3)
print foobar(variable)
print sin(3-2)

Η έξοδος μπορεί να σταλεί σε κάποιο αρχείο:

print "έκφραση" > "όνομα αρχείου"

ή σε άλλο πρόγραμμα διαμέσου μιας σωλήνωσης:

print "έκφραση" | "εντολή"

Ενσωματωμένες μεταβλητές[Επεξεργασία | επεξεργασία κώδικα]

Οι ενσωματωμένες μεταβλητές της Awk περιλαμβάνουν τις μεταβλητές των πεδίων: $1, $2, $3, ... (με $0 να είναι ολόκληρη η εγγραφή). Οι μεταβλητές αυτές δίνουν το κείμενο ή την τιμή κάθε πεδίου κειμένου μιας εγγραφής.

Υπάρχουν και άλλες ενσωματωμένες μεταβλητές:

  • NR: Μετρητής του αριθμού των εγγραφών εισόδου.
  • NF: Ο αριθμός των πεδίων σε μια εγγραφή εισόδου. Το τελευταίο πεδίο μπορεί να γραφεί και σαν $NF.
  • FILENAME: Το όνομα του τρέχοντος αρχείου εισόδου.
  • FS: Ο διαχωριστικός χαρακτήρας πεδίων ("field separator") που διαχωρίζει τα πεδία στην εγγραφή εισόδου. Η προκαθορισμένη του τιμή είναι "λευκό διάστημα" ("white space"), δηλαδή ο χαρακτήρας του κενού και οι χαρακτήρες-στηλοθέτες (tab characters). Η τιμή του FS μπορεί να τεθεί σε κάποιον άλλο χαρακτήρα για να αλλάξει ο διαχωριστής πεδίων.
  • RS: Περιέχει τον τρεχοντα διαχωριστικό χαρακτήρα εγγραφών ("record separator"). Ο προκαθορισμένος διαχωριστικός χαρακτήρας εγγραφών είναι η "αλλαγή γραμμής" ("newline"), επειδή συνήθως οι εγγραφές αντιστοιχούν στις γραμμές της εισόδου.
  • OFS: Περιέχει το διαχωριστή πεδίου εξόδου ("output field separator"), που διαχωρίζει τα πεδία όταν τα εμφανίζει η Awk. Η προκαθορισμένη του τιμή είναι ο χαρακτήρας κενού.
  • ORS: Περιέχει το διαχωριστή εγγραφής εξόδου ("output record separator"), που διαχωρίζει τις εγγραφές εξόδου όταν τις τυπώνει η Awk. Η προκαθορισμένη του τιμή είναι ο χαρακτήρας αλλαγής γραμμής.
  • OFMT: Αποθηκεύει τη μορφή της αριθμητικής εξόδου. Η προκαθορισμένη του τιμή είναι "%.6g".

Μεταβλητές και σύνταξη[Επεξεργασία | επεξεργασία κώδικα]

Το ονόματα των μεταβλητών μπορούν να χρησιμοποιούν οποιονδήποτε από τους χαρακτήρες [A-Za-z0-9_] αλλά δε μπορούν να είναι λέξεις-κλειδιά της γλώσσας. Οι τελεστές + - * / αναπαριστούν την πρόσθεση, την αφαίρεση, τον πολλαπλασιασμό και τη διαίρεση αντίστοιχα. Όταν δύο μεταβλητές (ή σταθερές συμβολοσειρές) τοποθετούνται η μια δίπλα στην άλλη, αυτό δηλώνει τη συνένωσή τους. Οι σταθερές συμβολοσειρές οριοθετούνται από διπλά εισαγωγικά. Οι εντολές δεν χρειάζεται να τερματίζονται με ελληνικά ερωτηματικά (semicolons). Τέλος, σχόλια μπορούν να προστεθούν σε ένα πρόγραμμα σαν γραμμές που αρχίζουν με το χαρακτήρα #.

Συναρτήσεις που ορίζονται από το χρήστη[Επεξεργασία | επεξεργασία κώδικα]

Οι συναρτήσεις ορίζονται παρόμοια με τη C, με τη λέξη-κλειδί function, ακολουθούμενη από το όνομα της συνάρτησης, τα ονόματα των παραμέτρων της και το σώμα της συνάρτησης. Για παράδειγμα:

function add_three (number) {
  return number + 3
}

Η συνάρτηση αυτή μπορεί να κληθεί ως εξής:

print add_three(36)     # Εμφανίζει 39

Οι συναρτήσεις μπορούν να έχουν μεταβλητές με τοπική εμβέλεια (scope): τα ονόματά τους τοποθετούνται στο τέλος της λίστας των παραμέτρων, αν και δεν τους δίνεται τιμή όταν καλείται η συνάρτηση. Συνηθίζεται να γράφεται κάποιο κενό στη λίστα των παραμέτρων πριν τις τοπικές μεταβλητές, για να ξεχωρίζουν από τις κανονικές μεταβλητές.

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

Παραδείγματα προγραμμάτων[Επεξεργασία | επεξεργασία κώδικα]

Γειά σου, κόσμε[Επεξεργασία | επεξεργασία κώδικα]

Το κλασικό παράδειγμα "Γειά σου, κόσμε" ("Hello world") γράφεται σε AWK ως εξής:

BEGIN {
    print "Γειά σου, κόσμε!"
    exit(0)
}

Το μόνο πρότυπο είναι το BEGIN και περιέχει ως ενέργεια την εντολή εκτύπωσης της συμβολοσειράς "Γειά σου, κόσμε", επομένως η εντολή αυτή θα εκτελεστεί κατά την εκκίνηση του προγράμματος και πριν διαβαστεί οποιοδήποτε input. Η εντολή exit χρειάζεται εδώ, ώστε το πρόγραμμα να μην προχωρήσει σε περαιτέρω επεξεργασία του input.

Εμφάνισε γραμμές μεγαλύτερες από 80 χαρακτήρες[Επεξεργασία | επεξεργασία κώδικα]

Τυπώνει όλες τις γραμμές που έχουν μήκος μεγαλύτερο από 80 χαρακτήρες. Η προεπιλεγμένη ενέργεια είναι η εμφάνιση της τρέχουσας γραμμής.

length($0) > 80

Εμφανίζει τον αριθμό των λέξεων[Επεξεργασία | επεξεργασία κώδικα]

Μετρά τις λέξεις της εισόδου και εμφανίζει τον αριθμό των γραμμών, των λέξεων και των χαρακτήρων (όπως το wc):

{
    w += NF
    c += length($0) + 1
}
END { print NR, w, c }

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

Σύνολο τελευταίων λέξεων[Επεξεργασία | επεξεργασία κώδικα]

{ s += $NF }
END { print s + 0 }

Η s αυξάνεται με την αριθμητική τιμή της $NF που είναι η τελευταία λέξη της γραμμής (όπως ορίζεται από το διαχωριστή πεδίων της AWK, που έχει την προκαθορισμένη τιμή του λευκού κενού). Η NF είναι ο αριθμός των πεδίων της τρέχουσας γραμμής, π.χ. 4. Επειδή $4 είναι η τιμή του τέταρτου πεδίου, η $NF δίνει πάντα την τιμή του τελευταίου πεδίου μιας γραμμής. Ο τελεστής $ παίρνει ένα όρισμα και έχει την υψηλότερη προτεραιότητα (operator precedence). Αν μια γραμμή δεν έχει πεδία, τότε η NF είναι 0, $0 είναι ολόκληρη η γραμμή, που είναι άδεια (εκτός από τα κενά που μπορεί να περιέχει), επομένως η αριθμητική τιμή τότε είναι 0.

Στο τέλος της εισόδου, το πρότυπο END ταιριάζει και τυπώνεται η s. Αν δεν έχουν υπάρξει γραμμές εισόδου, δε θα έχει δοθεί ποτέ τιμή στην s, η οποία και θα είναι η κενή συμβολοσειρά. Η πρόσθεση του μηδέν σε μια συμβολοσειρά αποτελεί ιδίωμα της AWK που εξαναγκάζει μια συμβολοσειρά να γίνει αριθμητική τιμή (coercion). Αντίθετα, η συνένωση με κενή συμβολοσειρά εξαναγκάζει έναν αριθμό να γίνει συμβολοσειρά, π.χ. s "". (Δεν υπάρχει τελεστής συνένωσης συμβολοσειρών, απλά αυτές τοποθετούνται η μια δίπλα στην άλλη.) Λόγω του εξαναγκασμού το πρόγραμμα τυπώνει 0 για κενή είσοδο, αλλιώς θα τύπωνε μια κενή γραμμή.

Ταίριασμα με ένα εύρος από γραμμές εισόδου[Επεξεργασία | επεξεργασία κώδικα]

$ yes Wikipedia | awk 'NR % 4 == 1, NR % 4 == 3 { printf "%6d  %s\n", NR, $0 }' | sed 7q
     1  Wikipedia
     2  Wikipedia
     3  Wikipedia
     5  Wikipedia
     6  Wikipedia
     7  Wikipedia
     9  Wikipedia
$

Η εντολή yes τυπώνει συνεχόμενα το όρισμά της (εξορισμού το γράμμα "y") σε μια γραμμή. Σε αυτό το παράδειγμα, η εντολή τυπώνει τη λέξη "Wikipedia". Η εντολή της ενέργειας τυπώνει τις γραμμές αριθμημένες. Η συνάρτηση printf προσομοιώνει την printf της C, και λειτουργεί με παρόμοιο τρόπο με την εντολή print που έχει προαναφερθεί. Το πρότυπο προς ταίριασμα λειτουργεί ως εξής: NR είναι ο αριθμός των εγγραφών, συνήθως οι γραμμές εισόδου, που έχει ήδη διαβάσει η AWK, δηλαδή ο τρέχων αριθμός γραμμής που αρχίζει από το 1 για την πρώτη γραμμή της εισόδου. Ο % είναι ο τελεστής υπολοίπου από διαίρεση (modulo). Η NR % 4 == 1 είναι αληθής για την πρώτη, την πέμπτη, την ένατη, κλπ, γραμμές της εισόδου ενώ η NR % 4 == 3 είναι αληθής για την τρίτη, την έβδομη, την ενδέκατη, κλπ, γραμμές της εισόδου. Το πρότυπο του εύρους είναι ψευδές μέχρι να ταιριάξει το πρώτο μέρος, στη γραμμή 1, και στη συνέχεια μένει αληθές μέχρι και όταν ταιριάξει το δεύτερο μέρος, στη γραμμή 3. Στη συνέχεια μένει ψευδές μέχρι το πρώτο μέρος να ταιριάξει πάλι στη γραμμή 5. Η εντολή sed χρησιμοποιείται για να τυπώσει τις πρώτες 7 γραμμές, ώστε η yes να μην τρέχει για πάντα. Αν είναι διαθέσιμη η εντολή head, είναι ισοδύναμη με την head -n7.

Όταν το πρώτο μέρος ενός προτύπου εύρους είναι πάντα αληθές, π.χ. 1, μπορεί να χρησιμοποιηθεί για να αρχίσει το εύρος στην αρχή της εισόδου. Όμοια, αν το δεύτερο μέρος είναι πάντα ψευδές, π.χ. 0, το εύρος εξακολουθεί μέχρι το τέλος της εισόδου, τότε η:

/^--κόψτε εδώ--$/, 0

τυπώνει γραμμές της εισόδου από την πρώτη γραμμή που ταιριάζει με την κανονική έκφραση ^--κόψτε εδώ--$ (μια γραμμή που περιέχει μόνο τη φράση "--κόψτε εδώ--"), μέχρι το τέλος.

Υπολογισμός συχνοτήτων λέξεων[Επεξεργασία | επεξεργασία κώδικα]

Ο υπολογισμός των συχνοτήτων λέξεων χρησιμοποιεί συσχετιστικούς πίνακες (associative arrays):

BEGIN {
    FS="[^a-zA-Z]+"
}
{
     for (i=1; i<=NF; i++)
          words[tolower($i)]++
}
END {
    for (i in words)
         print i, words[i]
}

Η ενότητα BEGIN θέτει το διαχωριστικό πεδίων να είναι κάθε ακολουθία από μη-αλφαβητικούς χαρακτήρες (τα διαχωριστικά μπορούν να είναι κανονικές εκφράσεις). Ακολουθεί μια ενέργεια που επαναλαμβάνεται σε κάθε γραμμή της εισόδου. Σε αυτήν την περίπτωση, για κάθε πεδίο της γραμμής, προστίθεται 1 στον αριθμό των φορών που αυτή η λέξη, που έχει μετατραπεί σε μικρά γράμματα, εμφανίζεται. Τέλος, στην ενότητα END, τυπώνονται οι λέξεις με τις συχνότητές τους. Η γραμμή

for (i in words)

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

Ταίριασμα προτύπου από τη γραμμή εντολών[Επεξεργασία | επεξεργασία κώδικα]

Το πρόγραμμα μπορεί να αναπαρασταθεί με πολλούς τρόπους. Ο πρώτος χρησιμοποιεί το κέλυφος Bourne για να δημιουργήσει ένα σενάριο κελύφους που κάνει τα πάντα και είναι ο συντομότερος τρόπος:

$ cat grepinawk
pattern=$1
shift
awk '/'$pattern'/ { print FILENAME ":" $0 }' $*
$

Το πρότυπο $pattern στην εντολή της awk δεν προστατεύεται από εισαγωγικά. Ένα πρότυπο από μόνο του ελέγχει αν ολόκληρη η γραμμή ($0) ταιριάζει. Η FILENAME περιέχει το τρέχον όνομα αρχείου. Όπως έχει προαναφέρθηκε, η awk δεν έχει τελεστή συνένωσης αλλά η απλή παράθεση δύο συμβολοσειρών αρκεί για τη συνένωσή τους. Το $0 επεκτείνεται στην αρχική γραμμή εισόδου.

Υπάρχουν διάφοροι τρόποι να γραφεί το παράδειγμα. Το παρακάτω σενάριο κελύφους έχει πρόσβαση στο περιβάλλον απευθείας μέσα από την awk:

$ cat grepinawk
pattern=$1
shift
awk '$0 ~ ENVIRON["pattern"] { print FILENAME ":" $0 }' $*
$

Το σενάριο αυτό χρησιμοποιεί την ENVIRON, που είναι πίνακας που αναπαριστά το περιβάλλον: οι δείκτες είναι ονόματα μεταβλητών και τα αποτελέσματα είναι τιμές μεταβλητών, παρόμοια σε λειτουργικότητα με τη συνάρτηση getenv διάφορων πρότυπων βιβλιοθηκών και του POSIX. Το σενάριο δημιουργεί μια μεταβλητή περιβάλλοντος pattern που περιέχει την πρώτη παράμετρο και στη συνέχεια τη διαγράφει και δίνει εντολή στην awk να αναζητήσει το πρότυπο pattern σε κάθε αρχείο.

Ο τελεστής ~ ελέγχει αν ο αριστερός του τελεστέος ταιριάζει με το δεξιό, ενώ ο αντίστροφος τελεστής είναι ο !~. Μια κανονική έκφραση είναι απλά συμβολοσειρά και μπορεί να αποθηκευτεί σε μια μεταβλητή.

Ο επόμενος τρόπος χρησιμοποιεί ανάθεση μεταβλητών της γραμμής εντολών, όπου μια παράμετρος στην awk μπορεί να θεωρηθεί σαν ανάθεση σε μια μεταβλητή:

$ cat grepinawk
pattern=$1
shift
awk '$0 ~ pattern { print FILENAME ":" $0 }' "pattern=$pattern" $*
$

Τέλος, ο ακόλουθος κώδικας είναι γραμμένος αμιγώς σε awk, χωρίς βοήθεια από κέλυφος ή γνώσεις για την υλοποίηση του σεναρίου awk (όπως κάνει η ανάθεση μεταβλητών της γραμμής εντολών παραπάνω), αλλά είναι μεγαλύτερος:

BEGIN {
    pattern = ARGV[1]
    for (i = 1; i < ARGC; i++) # διαγράφει την 1η παράμετρο
        ARGV[i] = ARGV[i + 1]
    ARGC—if (ARGC == 1) { # μόνο το πρότυπο υπήρχε, άρα διάβασε από την είσοδο
        ARGC = 2
        ARGV[1] = "-"
    }
}
$0 ~ pattern { print FILENAME ":" $0 }

Το BEGIN χρειάζεται όχι μόνο για να εξάγει την πρώτη παράμετρο, αλλά και για να την εμποδίσει από το να ερμηνευτεί σαν όνομα αρχείου όταν τελειώσει η ενότητα BEGIN. Η ARGC, που είναι ο αριθμός των παραμέτρων, είναι πάντα ≥1, επειδή η ARGV[0] είναι το όνομα της εντολής που εκτέλεσε το σενάριο, συνήθως η συμβολοσειρά "awk". Επίσης η ARGV[ARGC] είναι η κενή συμβολοσειρά, "". Ο χαρακτήρας # αρχίζει ένα σχόλιο μέχρι το τέλος της γραμμής.

Στην ενότητα if η awk ελέγχει αν πρέπει να διαβάσει από την είσοδο πριν εκτελέσει την εντολή. Αυτό σημαίνει ότι η εντολή

awk 'prog'

λειτουργεί μόνο επειδή το ότι δεν υπάρχουν ονόματα αρχείων ελέγχεται πριν εκτελεστεί το prog! Αν η ARGC τεθεί ίση με 1 ώστε να μην υπάρχουν παράμετροι, η awk απλά θα τερματίσει γιατί δε θα βλέπει άλλα αρχεία εισόδου. Είναι επομένως ανάγκη το διάβασμα από την είσοδο με το ειδικό όνομα αρχείου -.

Αυτόνομα σενάρια AWK[Επεξεργασία | επεξεργασία κώδικα]

Όπως και σε άλλες γλώσσες προγραμματισμού, είναι δυνατή η δημιουργία αυτόνομων σεναρίων σε AWK με τη χρήση της λεγόμενης σύνταξης "shebang", που τοποθετεί μια σήμανση στην αρχή του αρχείου για το πρόγραμμα με το οποίο εκτελούνται.

Για παράδειγμα, μπορεί να κατασκευαστεί μια εντολή του UNIX με όνομα hello.awk που να τυπώνει τη συμβολοσειρά "Γεια σου, κόσμε!", με τη δημιουργία ενός αρχείου hello.awk που να περιέχει τις εξής γραμμές:

#!/usr/bin/awk -f
BEGIN { print "Γεια σου, κόσμε!" }

Η επιλογή -f πληροφορεί την awk ότι η παράμετρος που ακολουθεί είναι το αρχείο από το οποίο θα διαβαστεί το πρόγραμμα awk και συμπληρώνεται από το κέλυφος τη στιγμή της εκτέλεσης.

Βιβλία[Επεξεργασία | επεξεργασία κώδικα]

Δείτε επίσης[Επεξεργασία | επεξεργασία κώδικα]

Παραπομπές[Επεξεργασία | επεξεργασία κώδικα]

  1. The Single UNIX Specification, Version 3, Utilities Interface Table
  2. Linux Standard Base Core Specification 4.0, Chapter 15. Commands and Utilities
  3. The A-Z of Programming Languages: AWK
  4. Raymond, Eric S.. «Applying Minilanguages». The Art of Unix Programming. Case Study: awk. Αρχειοθετήθηκε από το πρωτότυπο στις 30 Ιουλίου 2008. http://web.archive.org/web/20080730063308/http://www.faqs.org/docs/artu/ch08s02.html#awk. Ανακτήθηκε στις 11 Μαΐου 2010. «The awk action language is Turing-complete, and can read and write files.» 
  5. "AWK is a language for processing files of text. A file is treated as a sequence of records, and by default each line is a record. Each line is broken up into a sequence of fields, so we can think of the first word in a line as the first field, the second word as the second field, and so on. An AWK program is of [sic] a sequence of pattern-action statements. AWK reads the input a line at a time. A line is scanned for each pattern in the program, and for each pattern that matches, the associated action is executed." - Alfred V. Aho The A-Z of Programming Languages: AWK

Εξωτερικοί σύνδεσμοι[Επεξεργασία | επεξεργασία κώδικα]

Στο λήμμα αυτό έχει ενσωματωθεί κείμενο από το λήμμα AWK της Αγγλόγλωσσης Βικιπαίδειας, η οποία διανέμεται υπό την GNU FDL και την CC-BY-SA 3.0. (ιστορικό/συντάκτες).