505 γραμμές
		
	
	
	
		
			43 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			505 γραμμές
		
	
	
	
		
			43 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
+++
 | 
						||
title = 'Προγραμματισμός με gawk μέρος 2ο'
 | 
						||
date = '2000-04-01T00:00:00Z'
 | 
						||
description = ''
 | 
						||
author = 'DJ Art(mailto:djart@hellug.gr)'
 | 
						||
issue = ['Magaz 24']
 | 
						||
issue_weight = 3
 | 
						||
+++
 | 
						||
 | 
						||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 | 
						||
 | 
						||
*Το άρθρο αυτό αποτελεί το δεύτερο (και τελευταίο) μέρος της παρουσίασης της γλώσσας awk με στόχο την βοήθεια για την εκμάθησή της.*
 | 
						||
 | 
						||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 | 
						||
 | 
						||
**1. Ενσωματωμένες συναρτήσεις**
 | 
						||
-------------------------------------------------------
 | 
						||
 | 
						||
**2. Αριθμητικοί τελεστές**
 | 
						||
--------------------------------------------------
 | 
						||
 | 
						||
**3. Εντολές ελέγχου ροής**
 | 
						||
--------------------------------------------------
 | 
						||
 | 
						||
-   [3.1 If](#ss3.1)
 | 
						||
-   [3.2 Υποθετικός τελεστής](#ss3.2)
 | 
						||
-   [3.3 βρόγχοι](#ss3.3)
 | 
						||
 | 
						||
**4. Advanced Input**
 | 
						||
--------------------------------------------
 | 
						||
 | 
						||
-   [4.1 Next](#ss4.1)
 | 
						||
-   [4.2 Exit](#ss4.2)
 | 
						||
-   [4.3 Getline](#ss4.3)
 | 
						||
-   [4.4 Input από αρχείο](#ss4.4)
 | 
						||
-   [4.5 Input από εντολή](#ss4.5)
 | 
						||
-   [4.6 Τερματίζοντας το Input από αρχείο ή εντολή](#ss4.6)
 | 
						||
 | 
						||
**5. Advanced Output**
 | 
						||
---------------------------------------------
 | 
						||
 | 
						||
-   [5.1 Printf](#ss5.1)
 | 
						||
-   [5.2 Output σε αρχείο](#ss5.2)
 | 
						||
-   [5.3 Output σε εντολή](#ss5.3)
 | 
						||
-   [5.4 Τερματίζοντας το Output από αρχείο ή εντολή](#ss5.4)
 | 
						||
 | 
						||
**6. Συναρτήσεις**
 | 
						||
-----------------------------------------
 | 
						||
 | 
						||
-   [6.1 Δήλωση της συνάρτησης](#ss6.1)
 | 
						||
-   [6.2 Συνάρτηση με παραμέτρους](#ss6.2)
 | 
						||
-   [6.3 Η δήλωση return](#ss6.3)
 | 
						||
-   [6.4 Η συνάρτηση system](#ss6.4)
 | 
						||
 | 
						||
**7. Βιβλιογραφία**
 | 
						||
------------------------------------------
 | 
						||
 | 
						||
 | 
						||
### [1. Ενσωματωμένες συναρτήσεις]{#s1}
 | 
						||
 | 
						||
Παρακάτω, μπορείτε να δείτε έναν πίνακα με χρήσιμες συναρτήσεις που μπορείτε να χρησιμοποιήσετε σε ένα πρόγραμμά σας:
 | 
						||
 | 
						||
  ------------------------------------------------------------------------------- -------------------------------------------------------------------------------
 | 
						||
  \                                                                               Επιστρέφει το ημίτονο του 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.
 | 
						||
  ------------------------------------------------------------------------------- -------------------------------------------------------------------------------
 | 
						||
 | 
						||
 | 
						||
### [2. Αριθμητικοί τελεστές]{#s2}
 | 
						||
 | 
						||
Εδώ, επίσης θα δείτε έναν πίνακα, ο οποίος παρουσιάζει τους τελεστές που μπορείτε να χρησιμοποιήσετε για να κάνετε αριθμητικές πράξεις:
 | 
						||
 | 
						||
  ------------------------------------------------------------------------------- -------------------------------------------------------------------------------
 | 
						||
  \                                                                               Υψώνει το 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.
 | 
						||
 | 
						||
 | 
						||
### [3. Εντολές ελέγχου ροής]{#s3}
 | 
						||
 | 
						||
### [3.1 If]{#ss3.1}
 | 
						||
 | 
						||
Απο τη φύση της, η 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 :-("
 | 
						||
 | 
						||
### [3.2 Υποθετικός τελεστής]{#ss3.2}
 | 
						||
 | 
						||
Η gawk σας παρέχει με αυτόν τον τελεστή, ο οποίος αποτελείται από τρείς παραμέτρους, τη δυνατότητα να εφαρμόζετε if-ελέγχους ανά πάσα στιγμή μέσα στο πρόγραμμά
 | 
						||
σας. Η μορφή του είναι η εξής:
 | 
						||
 | 
						||
    υπόθεση ? αποτέλεσμα σε περίπτωση αλήθειας : εναλλακτικό αποτέλεσμα (σε μη-αληθινή περίπτωση)
 | 
						||
 | 
						||
Αυτός ο τελεστής καθιστά τα προγράμματά σας πιο ευανάγνωστα. Ας δούμε ένα παράδειγμα χρήσης του παραπάνω τελεστή σε περίπτωση όπου ανάλογα με τον αριθμό των
 | 
						||
αρχείων που αντιγράφηκαν, θέλουμε πληθυντικό ή ενικό:
 | 
						||
 | 
						||
    { print $1, "αρχεί" $1 != 1 ? "α αντιγράφηκαν" : "ο αντιγράφηκε" }
 | 
						||
 | 
						||
Αν θα θέλαμε να γράψουμε το παραπάνω, χρησιμοποιώντας το if, τότε θα γράφαμε:
 | 
						||
 | 
						||
    if ( $1 != 1 )
 | 
						||
       print $1, "αρχεία αντιγράφηκαν"
 | 
						||
    else
 | 
						||
       print $1, "αρχείο αντιγράφηκε"
 | 
						||
 | 
						||
### [3.3 βρόγχοι]{#ss3.3}
 | 
						||
 | 
						||
H awk υποστηρίζει τους βρόγχους do, for και while, όπως ακριβώς αυτοί συντάσσονται στην C. Μια γενική συμβουλή (για όλους τους βρόγχους) είναι να μην ξεχνάτε να
 | 
						||
χρησιμοποιείτε αγκύλες ({ }) όταν θέλετε μέσα στο βρόγχο να εκτελέσετε πάνω από μία εντολές. Ένα λάθος που γίνεται συχνά είναι ακριβώς αυτό, να ξεχνάει κανείς
 | 
						||
τις αγκύλες.
 | 
						||
 | 
						||
#### Do
 | 
						||
 | 
						||
Ο βρόγχος do (συνήθως καλείται και do-while) αποτελείται από δύο μέρη: τις εντολές που θέλουμε να εκτελέσουμε και τον (υποθετικό) έλεγχο. Προσέξτε πως αυτός ο
 | 
						||
βρόγχος έχει το χαρακτηριστικό να εκτελούνται οι εντολές που του δηλώνουμε τουλάχιστον μία φορά, καθώς ο υποθετικός έλεγχος που \"επιβάλλουμε\" αναγράφεται μετά
 | 
						||
την δήλωση των εντολών. Για να το καταλάβετε καλύτερα, ας δούμε τη σύνταξη του do:
 | 
						||
 | 
						||
    do 
 | 
						||
       εντολές
 | 
						||
    while (υπόθεση)
 | 
						||
 | 
						||
    π.χ:
 | 
						||
 | 
						||
    do 
 | 
						||
       print "Magaz kicks!!"
 | 
						||
    while ($1 != 1)
 | 
						||
 | 
						||
Το μήνυμα της print θα εκτελείται μέχρι το πρώτο πεδίο (\$1) να πάρει την τιμή 1. Όμως, ακόμα και αν το \$1 \"ξεκινάει\" με αρχική τιμή 1, τότε το μήνυμα θα
 | 
						||
τυπωθεί. Απλά, όταν θα γίνει ο έλεγχος και \"ικανοποιηθεί\" η while, δεν θα ξαναγυρίσουμε στο do, αλλά το πρόγραμμα θα προχωρήσει στις τυχόν παρακάτω εντολές.
 | 
						||
 | 
						||
#### For
 | 
						||
 | 
						||
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
 | 
						||
 | 
						||
Ο βρόγχος while είναι αρκετά απλός και μάλλον θα έχετε ήδη καταλάβει πως λειτουργεί (από το βρόγχο do-while). Σε αντίθεση με την do, οι εντολές εκτελούνται μόνο
 | 
						||
αν το αποτέλεσμα του υποθετικού ελέγχου, ο οποίος γίνεται στην αρχή του βρόγχου, είναι αληθής. Ας δούμε τη σύνταξή του:
 | 
						||
 | 
						||
    while (υπόθεση)
 | 
						||
      εντολή(ες και μήν ξεχάσετε τις αγκύλες :)
 | 
						||
 | 
						||
Γενικά, για τους βρόγχους, να έχετε υπ\' όψιν πως μέσα στις εντολές του βρόγχου, η μεταβλητή πάνω στην οποία γίνεται ο υποθετικός έλεγχος, πρέπει να αλλάζει,
 | 
						||
αλλιώς ο βρόγχος μας δεν τελειώνει ποτέ !!! (ατέρμων βρόγχος)
 | 
						||
 | 
						||
#### Έλεγχος στους βρόγχους
 | 
						||
 | 
						||
Όπως και στις υπόλοιπες γλώσσες προγραμματισμού, έτσι και στην awk, έχετε τη δυνατότητα να \"βγείτε\" από έναν βρόγχο (loop), \"νωρίτερα από το κανονικό\",
 | 
						||
δηλαδή χωρίς να \"ικανοποιηθεί\" κάποιος υποθετικός έλεγχος και τερματίσει ο βρόγχος. Αυτό μπορείτε να το κάνετε με δύο εντολές: την break και την continue.
 | 
						||
 | 
						||
Με την εντολή break **\*ΑΚΑΡΙΑΙΑ\*** τερματίζετε τον βρόγχο και, φυσικά, όσες εντολές ακολουθούν την break **\*ΜΕΣΑ\*** στον βρόγχο, δεν εκτελούνται, αλλά το
 | 
						||
πρόγραμμα θα συνεχίσει, εκτελώντας τις εντολές που τυχόν βρίσκονται μετά τον βρόγχο. Η εντολή break είναι σαν να εκτελείτε εκείνη την στιγμή τον υποθετικό
 | 
						||
έλεγχο του βρόγχου, αλλά το αποτέλεσμα **\*ΒΕΒΙΑΣΜΕΝΑ\*** (από την break) είναι μή αληθές (FALSE).
 | 
						||
 | 
						||
Αντίθετα, η εντολή continue αναγκάζει τον βρόγχο να εκτελέσει τον υποθετικό του έλεγχο. Όσες τυχόν εντολές βρίσκονται μετά την continue (μέσα στο βρόγχο) δεν
 | 
						||
εκτελούνται. Η continue δεν είναι σίγουρο πως θα \"τερματίσει\" το βρόγχο, αν το αποτέλεσμα του βρόγχου είναι αληθές (TRUE), τότε ο βρόγχος θα συνεχίσει να
 | 
						||
εκτελείται. Η continue είναι ιδιαίτερα χρήσιμη αν θέλετε (για κάποιο λόγο, για κάποια συνθήκη) να \"παρακάμψετε\" κάποιες εντολές του κώδικα.
 | 
						||
 | 
						||
 | 
						||
### [4. Advanced Input]{#s4}
 | 
						||
 | 
						||
Εξ ορισμού, η awk αυτόματα διαβάζει και εκτελεί συνέχεια την ίδια δουλειά: Διαβάζει μιά εγγραφή και αν ταιριάξει κάποιο πεδίο ή εγγραφή με το πρότυπο, τότε
 | 
						||
εκτελεί την πράξη. Όμως, η awk σας δίνει την δυνατότητα να \"επέμβετε\" σε όλην αυτήν την διαδικασία και να πάρετε την είσοδο (input) από ένα άλλο αρχείο ή να
 | 
						||
προκαλέσετε πρώιμο ξαναξεκίνημα της όλης διαδικασίας, να πάρετε είσοδο από την έξοδο κάποιας εντολής κλπ.
 | 
						||
 | 
						||
### [4.1 Next]{#ss4.1}
 | 
						||
 | 
						||
Η εντολή next \"υποχρεώνει\" την awk να διαβάσει την αμέσως επόμενη εγγραφή και να κάνει τα γνωστά (ταίριασμα των προτύπων και αν είναι αληθές, τότε εκτέλεση
 | 
						||
της πράξης κλπ.), δηλαδή αγνοείται πλήρως η παρούσα εγγραφή που επεξεργάζεται η awk.
 | 
						||
 | 
						||
### [4.2 Exit]{#ss4.2}
 | 
						||
 | 
						||
Η εντολή exit, χρησιμοποιούμενη σε πράξη, συμπεριφέρεται σαν να έφτασε το τέλος του αρχείου (που επεξεργάζεται η awk). Αυτό έχει σαν συνέπεια να σταματήσει,
 | 
						||
γενικότερα, η εκτέλεση του κώδικα, δεν εκτελούνται άλλες πράξεις, δεν ταιριάζονται άλλα πρότυπα. Στη συνέχεια, κανονικά, εκτελείται (αν υπάρχει, βέβαια) το
 | 
						||
ειδικό πρότυπο END.
 | 
						||
 | 
						||
Αν τώρα, χρησιμοποιήσουμε την εντολή exit μέσα στο ειδικό πρότυπο END, τότε τερματίζεται ολόκληρο το πρόγραμμα, δεν εκτελείται τίποτα άλλο στη συνέχεια.
 | 
						||
 | 
						||
### [4.3 Getline]{#ss4.3}
 | 
						||
 | 
						||
Η εντολή getline διαβάζει μία εγγραφή \"κατηγορηματικά\", επιστρέφει 1 αν η ανάγνωση της εγγραφής ήταν επιτυχής (θυμίζω πως εξ ορισμού η κάθε γραμμή ενός
 | 
						||
αρχείου αποτελεί μία εγγραφή), ή 0 αν δεν ήταν επιτυχής (δηλαδή αν έφτασε στο τέλος του αρχείου). Η getline συμπεριφέρεται \"κανονικά\", δηλαδή ορίζει με τον
 | 
						||
σωστό τρόπο το \$0, ορίζει τις μεταβλητές πεδίων και τις μεταβλητές FNR, NR και NF).
 | 
						||
 | 
						||
### [4.4 Input από αρχείο]{#ss4.4}
 | 
						||
 | 
						||
Έτσι, λοιπόν, η getline μπορεί να χρησιμεύσει για να πάρετε είσοδο δεδομένων από κάποιο αρχείο, το οποίο δεν αναφέρατε στην γραμμή εντολών. Η γενική μορφή, με
 | 
						||
την οποία χρησιμοποιούμε την getline σ\' αυτήν την περίπτωση είναι η getline \< \"filename\". Σε αυτήν την περίπτωση, αν το αρχείο υπάρχει και η getline διάβασε
 | 
						||
εγγραφή, επιστρέφει 1, αλλιώς αν έφτασε στο τέλος του αρχείου επιστρέφει 0, ενώ αν το αρχείο δεν υπάρχει επιστρέφει -1.
 | 
						||
 | 
						||
ΣΗΜΕΙΩΣΗ: Και πάλι, οι μεταβλητές \$0, οι μεταβλητές πεδίων και η NF ορίζονται κανονικά, ενώ οι μεταβλητές FNR και NR **ΔΕΝ ΑΛΛΑΖΟΥΝ, ΠΑΡΑΜΕΝΟΥΝ ΩΣ ΕΙΧΑΝ !!**
 | 
						||
 | 
						||
### [4.5 Input από εντολή]{#ss4.5}
 | 
						||
 | 
						||
Μιά άλλη περίπτωση όπου χρησιμοποιείται η getline, είναι η είσοδος από UNIX εντολή. Ας δούμε πως μπορούμε να συντάξουμε κάτι τέτοιο:
 | 
						||
 | 
						||
    while ("UNIX εντολή" | getline)
 | 
						||
      {
 | 
						||
       # ακολουθούν οι εντολές που θέλω να εκτελέσω
 | 
						||
       }
 | 
						||
 | 
						||
Φανταστείτε π.χ. πως θα θέλατε κάθε φορά που μπαίνει ένας χρήστης στο σύστημα, να τυπώνετε ένα μήνυμα (ή, τέλος πάντων, να κάνατε κάτι άλλο), τότε στη θέση της
 | 
						||
UNIX εντολής θα βάζατε το who ή και το who -u.
 | 
						||
 | 
						||
### [4.6 Τερματίζοντας το Input από αρχείο ή εντολή]{#ss4.6}
 | 
						||
 | 
						||
Καλό θα είναι, κάθε φορά που χρησιμοποιείτε την getline για να \"ανοίξετε\" ένα αρχείο ή μία εντολή, δηλαδή να πάρετε είσοδο από αυτά, να τα \"κλείνετε\" όταν
 | 
						||
τελειώσετε με αυτά. Υπάρχει ένας μέγιστος αριθμός \"ανοιχτών\" αρχείων/εντολών που επιτρέπεται σε έναν χρήστη (αυτός ο αριθμός ποικίλει από σύστημα σε σύστημα,
 | 
						||
αλλά και ανάλογα με τις ρυθμίσεις του διαχειριστή του συστήματος). Με το να \"κλείνετε\" τις εντολές/αρχεία που χρησιμοποιήσατε, ουσιαστικά μειώνετε την
 | 
						||
πιθανότητα να φτάσετε τον μέγιστο αριθμό. Λοιπόν, αυτό μπορείτε να το κάνετε με την εξής εντολή:
 | 
						||
 | 
						||
    close ("filename")
 | 
						||
 | 
						||
Στη θέση του filename μπορείτε να χρησιμοποιήσετε είτε το όνομα κάποιας μεταβλητής (η οποία περιέχει αρχείο/εντολή) είτε το όνομα της εντολής που
 | 
						||
χρησιμοποιήσατε (εδώ, προσέξτε να δηλώσετε την ακριβή εντολή που χρησιμοποιήσατε, π.χ. αν χρησιμοποιήσετε την who -u να γράψετε close (\"who -u\") \...).
 | 
						||
 | 
						||
 | 
						||
### [5. Advanced Output]{#s5}
 | 
						||
 | 
						||
Μερικές πιο ειδικευμένες δυνατότητες υπάρχουν στην awk για την έξοδο (output). Αυτές είναι: το \"όμορφο\" φορμάρισμα του κειμένου, η ανακατεύθυνση του output σε
 | 
						||
αρχεία (κειμένου) και η διασωλήνωση του output στην είσοδο (input) άλλων (εξωτερικών) εντολών του command prompt.
 | 
						||
 | 
						||
### [5.1 Printf]{#ss5.1}
 | 
						||
 | 
						||
Η εντολή 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----
 | 
						||
 | 
						||
### [5.2 Output σε αρχείο]{#ss5.2}
 | 
						||
 | 
						||
Όπως και στην περίπτωση της getline, έτσι και εδώ, μπορείτε να χρησιμοποιήσετε τα σύμβολα της ανακατεύθυνσης για να στείλετε την έξοδο κατ\' ευθείαν μέσα σε ένα
 | 
						||
αρχείο. Π.χ:
 | 
						||
 | 
						||
    printf("hello world\n") > "filename"
 | 
						||
    printf("hello world\n") >> "filename"
 | 
						||
 | 
						||
### [5.3 Output σε εντολή]{#ss5.3}
 | 
						||
 | 
						||
Σε αυτήν την περίπτωση, έχετε την δυνατότητα να στείλετε έξοδο (output) στην είσοδο (input) μιάς εξωτερικής εντολής του UNIX. Π.χ:
 | 
						||
 | 
						||
    printf("hello world\n") | "sort -t , "
 | 
						||
 | 
						||
### [5.4 Τερματίζοντας το Output από αρχείο ή εντολή]{#ss5.4}
 | 
						||
 | 
						||
Ακριβώς για τους ίδιους λόγους που αναφέραμε στην getline, έτσι και εδώ, καλό θα ήταν να \"κλείνετε\" ένα αρχείο ή μία εντολή αφού τελειώσετε με αυτά. Η σύνταξη
 | 
						||
είναι ακριβώς η ίδια: close (\"filename\") και στη θέση του filename χρησιμοποιείτε είτε όνομα αρχείου, είτε το όνομα της **ΑΚΡΙΒΟΥΣ** εντολής που τρέξατε με
 | 
						||
διασωλήνωση, είτε το όνομα κάποιας μεταβλητής που \"δείχνει\" σε αρχείο.
 | 
						||
 | 
						||
 | 
						||
### [6. Συναρτήσεις]{#s6}
 | 
						||
 | 
						||
**ΠΡΟΣΟΧΗ!!!**\
 | 
						||
Οι συναρτήσεις (που ορίζονται από τον χρήστη) δεν υπάρχουν στην \"αυθεντική\" awk, αλλά προστέθηκαν αργότερα στην nawk και υποστηρίζονται από την gawk.
 | 
						||
 | 
						||
Όπως θα καταλάβατε, εκτός από τις ενσωματωμένες συναρτήσεις η gawk σας επιτρέπει να φτιάξετε τις δικές σας. Μία συνάρτηση χρησιμεύει σε ένα πρόγραμμα αν θέλετε
 | 
						||
να επαναλάβετε τα ίδια κομμάτια κώδικα σε πολλά σημεία του προγράμματος, ώστε να μην ξαναγράφετε κάθε φορά το ίδιο πράγμα. Η χρήση των συναρτήσεων απαιτεί δύο
 | 
						||
βήματα: την δήλωση της συνάρτησης και την κλήση της συνάρτησης μέσα στο πρόγραμμα.
 | 
						||
 | 
						||
### [6.1 Δήλωση της συνάρτησης]{#ss6.1}
 | 
						||
 | 
						||
Παρακάτω, θα δούμε τον κώδικα που απαιτείται για να δηλώσετε μιά συνάρτηση. Επιπλέον, να σημειώσω πως δεν παίζει κανέναν ρόλο η θέση που θα δηλώσετε την
 | 
						||
συνάρτηση. Μπορείτε κάλλιστα να την δηλώσετε στο τέλος του προγράμματος.
 | 
						||
 | 
						||
    function όνομα_συνάρτησης(παράμετροι) {
 | 
						||
        κώδικας της συνάρτησης
 | 
						||
    }
 | 
						||
 | 
						||
Τώρα θα δούμε τη λειτουργία των συναρτήσεων μέσα από τρία παραδείγματα. Το πρώτο παράδειγμα θα δείχνει την συνάρτηση στην απλή της μορφή (χωρίς παραμέτρους), το
 | 
						||
δεύτερο παράδειγμα θα δείχνει τη χρήση, λειτουργία και χρησιμότητα των παραμέτρων, ενώ στο 3ο παράδειγμα, θα μιλήσουμε για την δήλωση return και θα δούμε το
 | 
						||
αντίστοιχο παράδειγμα.
 | 
						||
 | 
						||
    BEGIN { function1() }
 | 
						||
 | 
						||
    function function1() {
 | 
						||
       printf("Magaz τεύχος 24\n");
 | 
						||
       printf("Άρθρο για gawk\n");
 | 
						||
    }
 | 
						||
 | 
						||
Όταν τρέξουμε το πρόγραμμα, το αποτέλεσμα θα είναι να μας τυπώσει στην οθόνη το περιεχόμενο των δύο printf, όπως ορίζονται μέσα στην συνάρτηση. Δώστε ιδιαίτερη
 | 
						||
έμφαση στις παρενθέσεις της συνάρτησης, πάντα πρέπει να τις γράφετε (σε αντίθεση με τις ενσωματωμένες συναρτήσεις της awk, όπου είναι προαιρετική η αναγραφή των
 | 
						||
παρενθέσεων).
 | 
						||
 | 
						||
### [6.2 Συνάρτηση με παραμέτρους]{#ss6.2}
 | 
						||
 | 
						||
Όταν χρησιμοποιούμε παραμέτρους στη συνάρτηση, τότε η αριθμητική αξία της μεταβλητής που αποτελεί την παράμετρο, αντιγράφεται και μετά \"περνάει\" στην
 | 
						||
συνάρτηση. Αυτό έχει σαν αποτέλεσμα η αρχική τιμή της μεταβλητής-παραμέτρου να παραμένει αναλλοίωτη. Αυτό είναι ένα πλεονέκτημα, μπορεί να μας φανεί σε πολλές
 | 
						||
περιπτώσεις χρήσιμο. Βέβαια, υπάρχει πάντα και η δυνατότητα να αλλοιωθεί, θα το δούμε παρακάτω. Ας δούμε τώρα ένα παράδειγμα:
 | 
						||
 | 
						||
    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 και δεν αλλάζει.
 | 
						||
 | 
						||
### [6.3 Η δήλωση return]{#ss6.3}
 | 
						||
 | 
						||
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.
 | 
						||
 | 
						||
### [6.4 Η συνάρτηση system]{#ss6.4}
 | 
						||
 | 
						||
Η συνάρτηση system είναι ενσωματωμένη στην awk. Είναι διαφορετική από τις άλλες, δεν ανήκει ούτε στην κατηγορία των αριθμητικών ούτε στην κατηγορία των
 | 
						||
αλφαριθμητικών συναρτήσεων. Αυτό που πραγματικά κάνει είναι να εκτελεί το αλφαριθμητικό που της δόθηκε ως παράμετρος, επιτρέποντας στον προγραμματιστή να
 | 
						||
εκτελεί απ\'ευθείας εντολές μέσα από το πρόγραμμα. Η σύνταξη της system έχει ως εξής:
 | 
						||
 | 
						||
    system ("εντολή")
 | 
						||
 | 
						||
 | 
						||
### [7. Βιβλιογραφία]{#s7}
 | 
						||
 | 
						||
Για την επίτευξη αυτού του άρθρου (συμπεριλαμβανομένου, φυσικά, και του 1ου μέρους) συμβουλεύτηκα τις εξής πηγές:
 | 
						||
 | 
						||
-   Την man page της εντολής gawk (man gawk)
 | 
						||
-   Το βιβλίο \"Linux Unleashed\" της SAMS
 | 
						||
-   Το βιβλίο \"UNIX: Θεωρία και πράξη\" του Κώστα Ν. Γιαλελή
 | 
						||
 | 
						||
Αν θα θέλατε να κάνετε ένα βήμα παραπάνω από το άρθρο, θα σας συμβούλευα πριν ψάξετε οπουδήποτε αλλού, να διαβάσετε τουλάχιστον μία φορά το man page της gawk.
 | 
						||
Είναι πολύ κατατοπιστικό και πολύ περιεκτικό.
 | 
						||
 |