💾 Archived View for magaz.hellug.gr › 24 › 03_gawk › index.gmi captured on 2024-08-31 at 12:17:40. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-02-05)
-=-=-=-=-=-=-
DJ Art(mailto:djart@hellug.gr) Απρ 2000
Το άρθρο αυτό αποτελεί το δεύτερο (και τελευταίο) μέρος της παρουσίασης της γλώσσας awk με στόχο την βοήθεια για την εκμάθησή της.
1. Ενσωματωμένες συναρτήσεις
2. Αριθμητικοί τελεστές
3. Εντολές ελέγχου ροής
4. Advanced Input
5. Advanced Output
6. Συναρτήσεις
7. Βιβλιογραφία
Παρακάτω, μπορείτε να δείτε έναν πίνακα με χρήσιμες συναρτήσεις που μπορείτε να χρησιμοποιήσετε σε ένα πρόγραμμά σας:
--------------------------------------------------------------------------------
\ Επιστρέφει το ημίτονο του x sin(x)
cos(x) Επιστρέφει το συνημίτονο του x
int(x) Επιστρέφει το ακέραιο μέρος του x
log(x) Επιστρέφει το φυσικό λογάριθμο του x
exp(x) Eπιστρέφει το e υψωμένο στη δύναμη του x
sqrt(x) Επιστρέφει την τετραγωνική ρίζα του x
getline() Διαβάζει την επόμενη γραμμή από το αρχείο.
Επιστρέφει 0 για το τέλος του αρχείου, διαφορετικά,
επιστρέφει 1
rand() Επιστρέφει έναν τυχαίο αριθμό ανάμεσα στο 0 και στο 1.
--------------------------------------------------------------------------------
Εδώ, επίσης θα δείτε έναν πίνακα, ο οποίος παρουσιάζει τους τελεστές που μπορείτε να χρησιμοποιήσετε για να κάνετε αριθμητικές πράξεις:
--------------------------------------------------------------------------------
\ Υψώνει το x στη δύναμη του y x^y
x**y Κάνε ακριβώς την ίδια δουλειά με τον παραπάνω τελεστή
x%y Υπολογίζει το υπόλοιπο της διαίρεσης x/y
x+y Προσθέτει το x στο y
x-y Αφαιρεί το y από το x
x*y Πολλαπλασιάζει το x με το y
x/y Διαιρεί το x με το y
-x Επιστρέφει τον αντίθετο του x (αλλάζει το πρόσημο)
++x Αυξάνει τον x κατά 1 και χρησιμοποιεί την τιμή (όλου αυτού)
x++ Χρησιμοποιεί πρώτα την τιμή του x και μετά την αυξάνει κατά 1
--x (αντίστοιχα με τα παραπάνω)
x-- (αντίστοιχα με τα παραπάνω
x=y Αποδίδει την τιμή του y στον x
x+=y Ισοδυναμεί με την παράσταση x=x+y
x/=y Iσοδυναμεί με την παράσταση x=x/y
--------------------------------------------------------------------------------
Παραδείγματα
Ακόμα μπερδευόσαστε με τα x++ και ++x ; :-) Πάμε, λοιπόν, να δούμε μέσα από παραδείγματα τί ακριβώς προσφέρουν:
x++
Αυτή εδώ η παράσταση ισοδυναμεί με την παράσταση x=x+1. Λοιπόν, προσέξτε: όσοι ασχολούνται για πρώτη φορά με τον προγραμματισμό, πρέπει να δώσουν ιδιαίτερη προσοχή με το σύμβολο της ισότητας. Εδώ το = δεν σημαίνει ακριβώς "ίσον" !!! Το σύμβολο = χρησιμοποιείται για να αποδώσει τιμές. Δηλαδή, στην ισότητα x=x+1, δεν πρέπει κανείς να πάει και "να φέρει το x στο πρώτο μέλος, οπότε να μείνει 0=1" !!! Απλά, το = κάνει το εξής: αποδίδει στην μεταβλητή x την τιμή που υπάρχει στο δεξί μέρος του, δηλαδή, αν αρχικά είχαμε ορίσει ότι το x είναι ίσο με 3, τώρα, μετά από αυτήν την δήλωση, το x θα είναι ίσο με 4.
y = x++
Αυτή εδώ η παράσταση, αντιστοιχεί σε δύο παραστάσεις, στην y=x και στην x=x+1. Δηλαδή, αν αρχικά το x είναι ίσο με 3, τότε το y ισούται με 3 (ΠΡΟΣΟΧΗ εδώ), ενώ το x πιά ισούται με 4 !!!! Κοιτάξτε και το παρακάτω παράδειγμα για να καταλάβετε:
y = --x
Λοιπόν, και αυτή η παράσταση αντιστοιχεί σε άλλες δύο, στην x=x-1 και στην y=x. Μα, θα μου πείτε, αυτές οι δύο δεν έχουν διαφορά με τις παραπάνω. Πρέπει να λάβετε υπ' όψιν την σειρά με την οποία εκτελούνται οι παραστάσεις, δηλαδή εδω, ΠΡΩΤΑ μειώνεται η τιμή του x κατά 1 και ΜΕΤΑ αποδίδεται η τιμή (του μειωμένου πιά x) στην μεταβλητή y, δηλαδή αν είχαμε αρχικά ότι το x ισούται με 3, τότε τώρα πιά, το x ΑΛΛΑ ΚΑΙ ΤΟ y ισούται με 2.
Απο τη φύση της, η gawk έχει την εξής μορφή: αν το πρότυπο ικανοποιείται, τότε εκτελείται η πράξη. Φυσικά, έχετε τη δυνατότητα να γράψετε ένα πρόγραμμα με "υποθετική ροή". Αυτό μπορείτε να το κάνετε, φυσικά, με το if.
Η γενική δομή του if έχει ως εξής:
if (υπόθεση) εντολή που εκτελείται αν η υπόθεσή μας είναι αληθινή else εντολή που εκτελείται αν η υπόθεσή μας δεν είναι αληθινή
Η υπόθεσή μας μπορεί να είναι οποισδήποτε συνδυασμός προτύπων από αυτά που είπαμε στο 1ο μέρος. Τώρα, αν θέλετε να εκτελούνται περισσότερες από μία εντολές, μετά τον έλεγχο αληθείας της υπόθεσης, τότε θα πρέπει να "περικυκλώσετε" τις εντολές με αγκύλες ({ }), ακριβώς όπως και στη C.
Μπορείτε να χρησιμοποιήσετε πολλά if στη σειρά (και μετά από ένα else) με τον εξής τρόπο:
if ("Linux" in magaz_subject) print "We are studying Linux :-)" else if ("gawk" in magaz_subject) print "We are studying awk :-)" else print "We are doing nothing :-("
Η gawk σας παρέχει με αυτόν τον τελεστή, ο οποίος αποτελείται από τρείς παραμέτρους, τη δυνατότητα να εφαρμόζετε if-ελέγχους ανά πάσα στιγμή μέσα στο πρόγραμμά σας. Η μορφή του είναι η εξής:
υπόθεση ? αποτέλεσμα σε περίπτωση αλήθειας : εναλλακτικό αποτέλεσμα (σε μη-αληθινή περίπτωση)
Αυτός ο τελεστής καθιστά τα προγράμματά σας πιο ευανάγνωστα. Ας δούμε ένα παράδειγμα χρήσης του παραπάνω τελεστή σε περίπτωση όπου ανάλογα με τον αριθμό των αρχείων που αντιγράφηκαν, θέλουμε πληθυντικό ή ενικό:
{ print $1, "αρχεί" $1 != 1 ? "α αντιγράφηκαν" : "ο αντιγράφηκε" }
Αν θα θέλαμε να γράψουμε το παραπάνω, χρησιμοποιώντας το if, τότε θα γράφαμε:
if ( $1 != 1 ) print $1, "αρχεία αντιγράφηκαν" else print $1, "αρχείο αντιγράφηκε"
H awk υποστηρίζει τους βρόγχους do, for και while, όπως ακριβώς αυτοί συντάσσονται στην C. Μια γενική συμβουλή (για όλους τους βρόγχους) είναι να μην ξεχνάτε να χρησιμοποιείτε αγκύλες ({ }) όταν θέλετε μέσα στο βρόγχο να εκτελέσετε πάνω από μία εντολές. Ένα λάθος που γίνεται συχνά είναι ακριβώς αυτό, να ξεχνάει κανείς τις αγκύλες.
Ο βρόγχος do (συνήθως καλείται και do-while) αποτελείται από δύο μέρη: τις εντολές που θέλουμε να εκτελέσουμε και τον (υποθετικό) έλεγχο. Προσέξτε πως αυτός ο βρόγχος έχει το χαρακτηριστικό να εκτελούνται οι εντολές που του δηλώνουμε τουλάχιστον μία φορά, καθώς ο υποθετικός έλεγχος που "επιβάλλουμε" αναγράφεται μετά την δήλωση των εντολών. Για να το καταλάβετε καλύτερα, ας δούμε τη σύνταξη του do:
do εντολές while (υπόθεση) π.χ: do print "Magaz kicks!!" while ($1 != 1)
Το μήνυμα της print θα εκτελείται μέχρι το πρώτο πεδίο ($1) να πάρει την τιμή 1. Όμως, ακόμα και αν το $1 "ξεκινάει" με αρχική τιμή 1, τότε το μήνυμα θα τυπωθεί. Απλά, όταν θα γίνει ο έλεγχος και "ικανοποιηθεί" η while, δεν θα ξαναγυρίσουμε στο do, αλλά το πρόγραμμα θα προχωρήσει στις τυχόν παρακάτω εντολές.
O βρόγχος for είναι ένας πασίγνωστος βρόγχος στις γλώσσες προγραμματισμού. Ας δούμε κατ' ευθείαν την σύνταξή του για να καταλάβουμε τη λειτουργία του:
for (i = 0; i < 100; i++) { εντολή 1 εντολή 2 }
Παραπάνω, οι εντολές του βρόγχου θα εκτελεστούν 100 φορές!! Ας δούμε γιατί: Αρχικά, ορίζουμε μιά μεταβλητή, την i, η οποία θα μας χρησιμεύσει απλά και μόνο για το πόσες φορές θα εκτελεστεί ο βρόγχος, και δίνουμε στην i την τιμή 0. Μετά, η for κοιτάει τη 2η δήλωση στην παρένθεση (οι δηλώσεις, υπενθυμίζω, χωρίζονται με ;) και κάνει τον υποθετικό έλεγχο. Στην περίπτωσή μας, ελέγχεται αν η τιμή της μεταβλητής i είναι μικρότερη από 100 και αν είναι, τότε εκτελούνται οι εντολές που καθορίσαμε. Μετά (και εδώ φαίνεται η "δυναμη" της for), δεν χρειάζεται να "κανονίσουμε" εμείς την μεταβλητή i, αλλά έχουμε δηλώσει η i να αυξάνεται κατά
1. Η for λοιπόν, αυξάνει την τιμή της i και ξαναρχίζει: κάνει τον έλεγχο, εκτελεί της εντολές, αυξάνει την i κ.ο.κ. ... Όταν, λοιπόν, η i θα αποκτήσει την τιμή
100, τότε δεν θα εκτελεστούν οι εντολές, καθώς το αποτέλεσμα του ελέγχου 100 < 100 είναι ψευδές (το 100 δεν είναι μικρότερο από το 100 !! :)
Ο βρόγχος while είναι αρκετά απλός και μάλλον θα έχετε ήδη καταλάβει πως λειτουργεί (από το βρόγχο do-while). Σε αντίθεση με την do, οι εντολές εκτελούνται μόνο αν το αποτέλεσμα του υποθετικού ελέγχου, ο οποίος γίνεται στην αρχή του βρόγχου, είναι αληθής. Ας δούμε τη σύνταξή του:
while (υπόθεση) εντολή(ες και μήν ξεχάσετε τις αγκύλες :)
Γενικά, για τους βρόγχους, να έχετε υπ' όψιν πως μέσα στις εντολές του βρόγχου, η μεταβλητή πάνω στην οποία γίνεται ο υποθετικός έλεγχος, πρέπει να αλλάζει, αλλιώς ο βρόγχος μας δεν τελειώνει ποτέ !!! (ατέρμων βρόγχος)
Όπως και στις υπόλοιπες γλώσσες προγραμματισμού, έτσι και στην awk, έχετε τη δυνατότητα να "βγείτε" από έναν βρόγχο (loop), "νωρίτερα ��πό το κανονικό", δηλαδή χωρίς να "ικανοποιηθεί" κάποιος υποθετικός έλεγχος και τερματίσει ο βρόγχος. Αυτό μπορείτε να το κάνετε με δύο εντολές: την break και την continue.
Με την εντολή break *ΑΚΑΡΙΑΙΑ*** τερματίζετε τον βρόγχο και, φυσικά, όσες εντολές ακολουθούν την break ***ΜΕΣΑ*** στον βρόγχο, δεν εκτελούνται, αλλά το πρόγραμμα θα συνεχίσει, εκτελώντας τις εντολές που τυχόν βρίσκονται μετά τον βρόγχο. Η εντολή break είναι σαν να εκτελείτε εκείνη την στιγμή τον υποθετικό έλεγχο του βρόγχου, αλλά το αποτέλεσμα ***ΒΕΒΙΑΣΜΕΝΑ* (από την break) είναι μή αληθές (FALSE).
Αντίθετα, η εντολή continue αναγκάζει τον βρόγχο να εκτελέσει τον υποθετικό του έλεγχο. Όσες τυχόν εντολές βρίσκονται μετά την continue (μέσα στο βρόγχο) δεν εκτελούνται. Η continue δεν είναι σίγουρο πως θα "τερματίσει" το βρόγχο, αν το αποτέλεσμα του βρόγχου είναι αληθές (TRUE), τότε ο βρόγχος θα συνεχίσει να εκτελείται. Η continue είναι ιδιαίτερα χρήσιμη αν θέλετε (για κάποιο λόγο, για κάποια συνθήκη) να "παρακάμψετε" κάποιες εντολές του κώδικα.
Εξ ορισμού, η awk αυτόματα διαβάζει και εκτελεί συνέχεια την ίδια δουλειά: Διαβάζει μιά εγγραφή και αν ταιριάξει κάποιο πεδίο ή εγγραφή με το πρότυπο, τότε εκτελεί την πράξη. Όμως, η awk σας δίνει την δυνατότητα να "επέμβετε" σε όλην αυτήν την διαδικασία και να πάρετε την είσοδο (input) από ένα άλλο αρχείο ή να προκαλέσετε πρώιμο ξαναξεκίνημα της όλης διαδικασίας, να πάρετε είσοδο από την έξοδο κάποιας εντολής κλπ.
Η εντολή next "υποχρεώνει" την awk να διαβάσει την αμέσως επόμενη εγγραφή και να κάνει τα γνωστά (ταίριασμα των προτύπων και αν είναι αληθές, τότε εκτέλεση της πράξης κλπ.), δηλαδή αγνοείται πλήρως η παρούσα εγγραφή που επεξεργάζεται η awk.
Η εντολή exit, χρησιμοποιούμενη σε πράξη, συμπεριφέρεται σαν να έφτασε το τέλος του αρχείου (που επεξεργάζεται η awk). Αυτό έχει σαν συνέπεια να σταματήσει, γενικότερα, η εκτέλεση του κώδικα, δεν εκτελούνται άλλες πράξεις, δεν ταιριάζονται άλλα πρότυπα. Στη συνέχεια, κανονικά, εκτελείται (αν υπάρχει, βέβαια) το ειδικό πρότυπο END.
Αν τώρα, χρησιμοποιήσουμε την εντολή exit μέσα στο ειδικό πρότυπο END, τότε τερματίζεται ολόκληρο το πρόγραμμα, δεν εκτελείται τίποτα άλλο στη συνέχεια.
Η εντολή getline διαβάζει μία εγγραφή "κατηγορηματικά", επιστρέφει 1 αν η ανάγνωση της εγγραφής ήταν επιτυχής (θυμίζω πως εξ ορισμού η κάθε γραμμή ενός αρχείου αποτελεί μία εγγραφή), ή 0 αν δεν ήταν επιτυχής (δηλαδή αν έφτασε στο τέλος του αρχείου). Η getline συμπεριφέρεται "κανονικά", δηλαδή ορίζει με τον σωστό τρόπο το $0, ορίζει τις μεταβλητές πεδίων και τις μεταβλητές FNR, NR και NF).
Έτσι, λοιπόν, η getline μπορεί να χρησιμεύσει για να πάρετε είσοδο δεδομένων από κάποιο αρχείο, το οποίο δεν αναφέρατε στην γραμμή εντολών. Η γενική μορφή, με την οποία χρησιμοποιούμε την getline σ' αυτήν την περίπτωση είναι η getline < "filename". Σε αυτήν την περίπτωση, αν το αρχείο υπάρχει και η getline διάβασε εγγραφή, επιστρέφει 1, αλλιώς αν έφτασε στο τέλος του αρχείου επιστρέφει 0, ενώ αν το αρχείο δεν υπάρχει επιστρέφει -1.
ΣΗΜΕΙΩΣΗ: Και πάλι, οι μεταβλητές $0, οι μεταβλητές πεδίων και η NF ορίζονται κανονικά, ενώ οι μεταβλητές FNR και NR ΔΕΝ ΑΛΛΑΖΟΥΝ, ΠΑΡΑΜΕΝΟΥΝ ΩΣ ΕΙΧΑΝ !!
Μιά άλλη περίπτωση όπου χρησιμοποιείται η getline, είναι η είσοδος από UNIX εντολή. Ας δούμε πως μπορούμε να συντάξουμε κάτι τέτοιο:
while ("UNIX εντολή" | getline) { # ακολουθούν οι εντολές που θέλω να εκτελέσω }
Φανταστείτε π.χ. πως θα θέλατε κάθε φορά που μπαίνει ένας χρήστης στο σύστημα, να τυπώνετε ένα μήνυμα (ή, τέλος πάντων, να κάνατε κάτι άλλο), τότε στη θέση της UNIX εντολής θα βάζατε το who ή και το who -u.
Καλό θα είναι, κάθε φορά που χρησιμοποιείτε την getline για να "ανοίξετε" ένα αρχείο ή μία εντολή, δηλαδή να πάρετε είσοδο από αυτά, να τα "κλείνετε" όταν τελειώσετε με αυτά. Υπάρχει ένας μέγιστος αριθμός "ανοιχτών" αρχείων/εντολών που επιτρέπεται σε έναν χρήστη (αυτός ο αριθμός ποικίλει από σύστημα σε σύστημα, αλλά και ανάλογα με τις ρυθμίσεις του διαχειριστή του συστήματος). Με το να "κλείνετε" τις εντολές/αρχεία που χρησιμοποιήσατε, ουσιαστικά μειώνετε την πιθανότητα να φτάσετε τον μέγιστο αριθμό. Λοιπόν, αυτό μπορείτε να το κάνετε με την εξής εντολή:
close ("filename")
Στη θέση του filename μπορείτε να χρησιμοποιήσετε είτε το όνομα κάποιας μεταβλητής (η οποία περιέχει αρχείο/εντολή) είτε το όνομα της εντολής που χρησιμοποιήσατε (εδώ, προσέξτε να δηλώσετε την ακριβή εντολή που χρησιμοποιήσατε, π.χ. αν χρησιμοποιήσετε την who -u να γράψετε close ("who -u") ...).
Μερικές πιο ειδικευμένες δυνατότητες υπάρχουν στην awk για την έξοδο (output). Αυτές είναι: το "όμορφο" φορμάρισμα του κειμένου, η ανακατεύθυνση του output σε αρχεία (κειμένου) και η διασωλήνωση του output στην είσοδο (input) άλλων (εξωτερικών) εντολών του command prompt.
Η εντολή print που είδαμε (στο 1ο μέρος), είναι αρκετά απλή και το output της είναι και αυτό αρκετά απλό. Αν, όμως, θέλετε να έχετε μορφοποιημένη την έξοδο του προγράμματός σας (παραγωγή στηλών, για παράδειγμα), τότε θα πρέπει να χρησιμοποιήσετε την δανεισμένη από τη C εντολή, την printf. H printf έχει την εξής γενική μορφή:
printf("αλφαριθμητικό ελέγχου", λίστα_ορισμάτων, 1ο όρισμα, 2ο όρισμα, κ.ο.κ.)
Το αλφαριθμητικό ελέγχου, μπορεί να αποτελείται από τα εξής στοιχεία:
1. Απλούς χαρακτήρες (δηλαδή κείμενο)
2. ειδικούς μεταχαρακτήρες (θυμάστε το \n π.χ.)
3. Τις διαταγές φόρμας
Ας δούμε από ένα παράδειγμα για τα παραπάνω τρία στοιχεία, και μετά να μιλήσουμε περισσότερο για τις διαταγές φόρμας:
1. printf("hello world")
2. printf("\f")
3. printf("%22s", "Magaz")
4. Και φυσικά, συνδυασμό όλων αυτών των στοιχείων (θα το δούμε)
Λοιπόν, κάθε διαταγή φόρμας αποτελείται από 3 μέρη. Στο 1ο μέρος, ΠΑΝΤΑ, γράφουμε το σύμβολο του ποσοστού (%). Κάθε διαταγή φόρμας αρχίζει με αυτό το σύμβολο. Το 2ο μέρος συμπληρώνεται προαιρετικά. Συμπληρώνεται με αριθμούς, οι οποίοι υποδηλώνουν το μέγιστο μήκος της εξόδου. Τέλος, το 3ο μέρος αποτελείται από ειδικούς χαρακτήρες, οι οποίοι υποδηλώνουν το είδος της εξόδου (αν είναι αλφαριθμητικό, αν είναι δεκαδικός αριθμός κλπ.) Θα μιλήσουμε τώρα αναλυτικότερα για το 2ο μέρος και μετά θα δούμε έναν πίνακα με τους χαρακτήρες του 3ου μέρους.
Ο αριθμός, το εύρος πεδίου, αποτελείται από δύο αριθμούς οι οποίοι χωρίζονται με μία τελεία (.), δηλαδή είναι της μορφής x.y. Αν η έξοδος μας είναι δεκαδικός αριθμός, τότε ο αριθμός αριστερά από την τελεία υποδηλώνει τον αριθμό ψηφίων ΟΛΟΥ του αριθμού (συμπεριλαμβανόμενης της τελείας (.) του αριθμού), ενώ ο αριθμός δεξιά από την τελεία υποδηλώνει τον αριθμό ψηφίων του δεκαδικού μέρους του αριθμού. Αν τώρα, η έξοδος μας δεν είναι δεκαδικός αριθμός, αλλά ο,τιδήποτε άλλο, τότε ο αριθμός αριστερά από την τελεία είναι ο ελάχιστος αριθμός ψηφίων/χαρακτήρων αυτού που θα τυπώσουμε, ενώ ο αριθμός δεξιά της τελείας είναι ο μέγιστος αριθμός ψηφίων/χαρακτήρων και ο "πραγματικός" αριθμός των ψηφίων/χαρακτήρων που τελικά θα εκτυπωθούν. Δηλαδή, μπορείτε κάλλιστα να παραλείψετε τον αριθμό αριστερά της τελείας (π.χ. %.4s)
ΣΗΜΕΙΩΣΕΙΣ:
Αν θέλετε μέσα από την printf να τυπώσετε τον χαρακτήρα %, τότε θα γράψετε μέσα στον κώδικά σας %%.
Εξ ορισμού, η έξοδος της printf είναι σε δεξιά στοίχιση. Αν θέλετε να έχετε αριστερή, τότε μπροστά από τον αριθμό που βρίσκεται αριστερά της τελείας (στο εύρος πεδίου) βάζετε το σύμβολο μείον (-).
Παρακάτω, βλέπετε τον πίνακα με τους χαρακτήρες που μπορείτε να χρησιμοποιήσετε. Στη συνέχεια θα δούμε και παραδείγματα.
--------------------------------------------------------------------------------
\ Σημασία Κωδικός φόρμας
%c Χαρακτήρας ASCII
%d Ακέραιος δεκαδικός αριθμός
%i Το ίδιο με το %d
%e Εκτύπωση δεκαδικού αριθμού κινητής υποδιαστολής με επιστημονική
σημειογραφία, δηλαδή της μορφής [-]x.xxxxe[-/+]xxx
%f Δεκαδικός κινητής υποδιαστολής
%g Η awk κρίνει και διαλέγει για έναν αριθμό μία από τις μορφές %e και
%f (όποια έχει μικρότερο μήκος) και, παράλληλα, "απαλοίφει" άχρηστα μηδενικά
%o Μη προσημασμένος (χωρίς πρόσημο) ακέραιος οκταδικός αριθμός
%s Αλφαριθμητικό
%x Μη προσημασμένος ακέραιος δεκαεξαδικός αριθμός (με πεζά τα abcdef)
%X Μη προσημασμένος ακέραιος δεκαεξαδικός αριθμός (με κεφαλαία τα ABCDEF)
--------------------------------------------------------------------------------
Επειδή θέλω να σας δείξω την λειτουργία του εύρους πεδίου, θα συμβολίζω τα κενά με παύλα (-), ώστε να μπορείτε να μετρήσετε τους χαρακτήρες και τα κενά (και να βγάλετε τα συμπεράσματά σας):
printf("%10d\n", 29) (θα έχει σαν αποτέλεσμα:) --------29 printf("%-10d\n", 29) 29-------- printf("%10.3f\n", 123.56) ---123.560 printf("%15s\n", "Linux Magaz") ----Linux Magaz printf("%-15s\n", "Linux Magaz") Linux Magaz----
Όπως και στην περίπτωση της getline, έτσι και εδώ, μπορείτε να χρησιμοποιήσετε τα σύμβολα της ανακατεύθυνσης για να στείλετε την έξοδο κατ' ευθείαν μέσα σε ένα αρχείο. Π.χ:
printf("hello world\n") > "filename" printf("hello world\n") >> "filename"
Σε αυτήν την περίπτωση, έχετε την δυνατότητα να στείλετε έξοδο (output) στην είσοδο (input) μιάς εξωτερικής εντολής του UNIX. Π.χ:
printf("hello world\n") | "sort -t , "
Ακριβώς για τους ίδιους λόγους που αναφέραμε στην getline, έτσι και εδώ, καλό θα ήταν να "κλείνετε" ένα αρχείο ή μία εντολή αφού τελειώσετε με αυτά. Η σύνταξη είναι ακριβώς η ίδια: close ("filename") και στη θέση του filename χρησιμοποιείτε είτε όνομα αρχείου, είτε το όνομα της ΑΚΡΙΒΟΥΣ εντολής που τρέξατε με διασωλήνωση, είτε το όνομα κάποιας μεταβλητής που "δείχνει" σε αρχείο.
ΠΡΟΣΟΧΗ!!!
Οι συναρτήσεις (που ορίζονται από τον χρήστη) δεν υπάρχουν στην "αυθεντική" awk, αλλά προστέθηκαν αργότερα στην nawk και υποστηρίζονται από την gawk.
Όπως θα καταλάβατε, εκτός από τις ενσωματωμένες συναρτήσεις η gawk σας επιτρέπει να φτιάξετε τις δικές σας. Μία συνάρτηση χρησιμεύει σε ένα πρόγραμμα αν θέλετε να επαναλάβετε τα ίδια κομμάτια κώδικα σε πολλά σημεία του προγράμματος, ώστε να μην ξαναγράφετε κάθε φορά το ίδιο πράγμα. Η χρήση των συναρτήσεων απαιτεί δύο βήματα: την δήλωση της συνάρτησης και την κλήση της συνάρτησης μέσα στο πρόγραμμα.
Παρακάτω, θα δούμε τον κώδικα που απαιτείται για να δηλώσετε μιά συνάρτηση. Επιπλέον, να σημειώσω πως δεν παίζει κανέναν ρόλο η θέση που θα δηλώσετε την συνάρτηση. Μπορείτε κάλλιστα να την δηλώσετε στο τέλος του προγράμματος.
function όνομα_συνάρτησης(παράμετροι) { κώδικας της συνάρτησης }
Τώρα θα δούμε τη λειτουργία των συναρτήσεων μέσα από τρία παραδείγματα. Το πρώτο παράδειγμα θα δείχνει την συνάρτηση στην απλή της μορφή (χωρίς παραμέτρους), το δεύτερο παράδειγμα θα δείχνει τη χρήση, λειτουργία και χρησιμότητα των παραμέτρων, ενώ στο 3ο παράδειγμα, θα μιλήσουμε για την δήλωση return και θα δούμε το αντίστοιχο παράδειγμα.
BEGIN { function1() } function function1() { printf("Magaz τεύχος 24\n"); printf("Άρθρο για gawk\n"); }
Όταν τρέξουμε το πρόγραμμα, το αποτέλεσμα θα είναι να μας τυπώσει στην οθόνη το περιεχόμενο των δύο printf, όπως ορίζονται μέσα στην συνάρτηση. Δώστε ιδιαίτερη έμφαση στις παρενθέσεις της συνάρτησης, πάντα πρέπει να τις γράφετε (σε αντίθεση με τις ενσωματωμένες συναρτήσεις της awk, όπου είναι προαιρετική η αναγραφή των παρενθέσεων).
Όταν χρησιμοποιούμε παραμέτρους στη συνάρτηση, τότε η αριθμητική αξία της μεταβλητής που αποτελεί την παράμετρο, αντιγράφεται και μετά "περνάει" στην συνάρτηση. Αυτό έχει σαν αποτέλεσμα η αρχική τιμή της μεταβλητής-παραμέτρου να παραμένει αναλλοίωτη. Αυτό είναι ένα πλεονέκτημα, μπορεί να μας φανεί σε πολλές περιπτώσεις χρήσιμο. Βέβαια, υπάρχει πάντα και η δυνατότητα να αλλοιωθεί, θα το δούμε παρακάτω. Ας δούμε τώρα ένα παράδειγμα:
BEGIN { variable = 0; function1(variable); printf("Η τιμή της μεταβλητής variable είναι: %d\n", variable); } function function1(variable2) { variable2++; printf("Η τιμή της μεταβλητής variable2 είναι: %d\n", variable2); }
Όταν εκτελέσουμε το πρόγραμμα θα δούμε πως θα μας τυπωθούν στην οθόνη δύο γραμμές. Η πρώτη γραμμή (που θα προέρχεται από την συνάρτηση) θα λέει πως η variable2 είναι ίση με 1, ενώ η δεύτερη θα λέει πως η variable είναι ίση με 0. Βλέπετε, λοιπόν, πως η τιμή της variable αντιγράφεται στην variable2 και δεν αλλάζει.
H return έχει δύο λειτουργίες: είτε να επιστρέψετε την τιμή της παραμέτρου, είτε να βγείτε από την συνάρτηση νωρίτερα. Η σύνταξή της είναι: return όνομα_μεταβλητής. Μπορείτε σε κάθε συνάρτηση να επιστρέψετε την τιμή μόνο μίας μεταβλητής, όχι παραπάνω. Ας δούμε το παράδειγμα:
BEGIN { variable = 0; function1(variable); printf("Η τιμή της μεταβλητής variable είναι: %d\n", variable); } function function1(variable2) { variable2++; printf("Η τιμή της μεταβλητής variable2 είναι: %d\n", variable2); return variable2; }
Σε αυτήν την περίπτωση, θα τυπωθούν δύο γραμμές πάλι. Και στις δύο γραμμές η τιμή των μεταβλητών θα είναι ίση με 1, καθώς η τιμή της variable2 επέστρεψε στην τιμή της variable.
Η συνάρτηση system είναι ενσωματωμένη στην awk. Είναι διαφορετική από τις άλλες, δεν ανήκει ούτε στην κατηγορία των αριθμητικών ούτε στην κατηγορία των αλφαριθμητικών συναρτήσεων. Αυτό που πραγματικά κάνει είναι να εκτελεί το αλφαριθμητικό που της δόθηκε ως παράμετρος, επιτρέποντας στον προγραμματιστή να εκτελεί απ'ευθείας εντολές μέσα από το πρόγραμμα. Η σύνταξη της system έχει ως εξής:
system ("εντολή")
Για την επίτευξη αυτού του άρθρου (συμπεριλαμβανομένου, φυσικά, και του 1ου μέρους) συμβουλεύτηκα τις εξής πηγές:
Αν θα θέλατε να κάνετε ένα βήμα παραπάνω από το άρθρο, θα σας συμβούλευα πριν ψάξετε οπουδήποτε αλλού, να διαβάσετε τουλάχιστον μία φορά το man page της gawk. Είναι πολύ κατατοπιστικό και πολύ περιεκτικό.