Λειτουργικά Συστήματα 5η εργαστηριακή άσκηση Κειμενογράφος nano Κανονικές Εκφράσεις (Regular Expressions) Δρ. Εύη Φαλιάγκα
Κειμενογράφος nano Για να ανοίξετε ένα έγγραφο πρέπει να πληκτρολογήσετε το όνομα του editor και το όνομα του εγγράφου με το πλήρες path (εκτός και αν αυτό βρίσκεται στον current κατάλογο). Παράδειγμα: nano /user/file1.txt Η παραπάνω εντολή θα ανοίξει το αρχείο file1.txt που βρίσκεται στον κατάλογο /user/. Αν το έγγραφο βρίσκεται στον κατάλογο που είστε ήδη τότε πληκτρολογείται μόνο το όνομα του αρχείου. Παράδειγμα: nano myfile.txt Στην παραπάνω εικόνα η πρώτη γραμμή δείχνει την έκδοση του nano (2.2.6) και το αρχείο που έχετε ανοίξει File: /etc/fstab. Όλα τα υπόλοιπα από κάτω είναι τα περιεχόμενα του αρχείου. Κάτω βλέπουμε να γράφει:read 13 lines (Warning: No write permission). Το αρχείο δηλαδή περιέχει 13 γραμμές και δεν έχουμε δικαίωμα εγγραφής. Δεν μπορούμε να το αλλάξουμε, παρά μόνο να το διαβάσουμε. Κάτωκάτω, βλέπουμε το μενού βοηθείας. Αυτά που βλέπετε ως ^W, ^R, ^G κλπ, είναι τα λεγόμενα keystrokes που μπορούμε να χρησιμοποιήσουμε για να κάνουμε edit το αρχείο. Το σύμβολο ^ αντιστοιχίστε το με το πλήκτρο CTRL. Δηλαδή, CTRL+R = Read File, CTRL+W = Where Is.. κλπ. Αν ανοίξετε ένα αρχείο που δεν υπάρχει, τότε ο nano θα ανοίξει ένα κενό αρχείο για να γράψετε σε αυτό. Στον nano πλοηγούμαστε με τα βελάκια. Δεξιά-Αριστερά- 2
Πάνω-Κάτω. Εναλλακτικά, αλλάζουμε ολόκληρες σελίδες με το PgUp και PgDown. Τα Home και End πάνε στην αρχή και το τέλος κάποιας γραμμής, αντίστοιχα. Keystrokes Παρακάτω θα δούμε μερικά από τα σημαντικότερα keystrokes που θα σας χρειαστούν. CTRL+W = Where Is. Με αυτό ψάχνουμε για ένα συγκεκριμένο γράμμα-λέξη μέσα στο κείμενο. Πατάμε [ENTER] για να δούμε το αποτέλεσμα. Αν υπάρχουν περισσότερα από ένα αποτελέσματα μπορούμε να τα εντοπίσουμε όλα, ένα προς ένα πατώντας ξανά CTRL+W και [ENTER]. Η προηγούμενη αναζήτηση μένει αποθηκευμένη. CTRL+K = Cut text. Όπως καταλαβαίνεται, με αυτό το keystroke κάνουμε Cut μια γραμμή. Από το σημείο που βρίσκεται ο κέρσορας και μετά. CTRL+U = Uncut text. Είναι σαν το paste. Την γραμμή που κάναμε πριν Cut, αυτός ο συνδυασμός πλήκτρων το κάνει paste. Αν ο κέρσορας βρίσκεται εντελώς αριστερά(στην αρχή), τότε το κάνει paste ακριβώς από πάνω. Διαφορετικά στα δεξιά του κέρσορα. CTRL+\ = Search and replace. Το σύμβολο backslash (\) βρίσκεται συνήθως πάνω από το Enter και κάτω από το Backspace. Το search and replace είναι μια πολύ χρήσιμη λειτουργία. Πρώτα εντοπίζεται το κείμενο που θέλετε και έπειτα το αντικαθιστάτε με κάποιο άλλο. Αν υπάρχουν περισσότερα από ένα αποτελέσματα και θέλετε να τα αντικαταστήστε όλα, πατήστε το πλήκτρο A. CTRL+6 = Mark Set. Αυτό ξεκινά και μαρκάρει όλες τις γραμμές στις οποίες πλοηγούμαστε. Για να το διακόψουμε πατάμε ξανά CTRL+6 = Mark Unset. Ότι έχουμε μαρκάρει μπορούμε να τα κάνουμε ή Cut ή Copy. Esc και backslash (\) Προσέξτε ότι όπου χρησιμοποιούμε το ESC, ενεργοποιούμε μια λειτουργία. Αυτό δεν είναι keystroke. Δηλαδή δεν κρατάμε πατημένο το ESC και μετά το backslash. Πατάμε πρώτα το ESC μια φορά και μετά το backslash. Έτσι πηγαίνουμε στην αρχή του κειμένου. 3
Esc και Forward Slash (/) πάμε στο τέλος του κειμένου. ESC και το πλήκτρο 6 είναι το Copy. Αποθήκευση Για να αποθηκεύσουμε τις αλλαγές που έχουμε κάνει σε ένα έγγραφο, υπάρχουν δυο τρόποι. 1. CTRL+O = WriteOut. Αυτός ο συνδυασμός πλήκτρων θα γράψει τις αλλαγές στο έγγραφο. Μετά πατάμε CTRL+X για έξοδο (exit). 2. CTRL+X = Exit. Μπορούμε να πατήσουμε απευθείας το keystroke της εξόδου. Ο nano θα μας ρωτήσει αν θέλουμε να αποθηκεύσουμε τις αλλαγές (αλλιώς θα καταστραφούν), εκεί πατάμε το πλήκτρο Y = yes και κάνουμε έξοδο με αποθήκευση. Αν δεν θέλουμε αποθήκευση των αλλαγών, πατάμε το N = no. Text Manipulation µε τις grep, fgrep, egrep Το grep είναι μία εντολή που ψάχνει ένα ή περισσότερα από ένα αρχεία για γραµµές που περιέχουν strings ενός συγκεκριμένου πρότυπου (pattern). Οι γραµµές που εµφανίζονται στην οθόνη. Η πιο απλή περίπτωση είναι ένα fixed string pattern - σταθερή ακολουθία χαρακτήρων. Υπάρχουν όµως και πιο πολύπλοκα που καλούνται regular expressions. Το fgrep (fast ή fixed) utility χρησιμοποιείται µόνο για fixed character strings. Το egrep (extended) utility χρησιμοποιείται για full regular expressions. Παραδείγματα: grep student pass: Στο αρχείο pass ψάχνουµε το string student grep staff pass pass1: Στα δύο αρχεία pass και pass1 ψάχνουµε το string staff grep «name surname» pass: Στο αρχείο pass ψάχνουµε το string «name surname». To string όταν περιέχει κενό πρέπει να µπει μέσα σε διπλά ή μονά εισαγωγικά. Μια εντολή της μορφής grep student staff pass θα έψαχνε στα αρχεία staff και pass να βρει το string student (το 1ο όρισμα είναι το string, ενώ τα υπόλοιπα, εδώ 2o & 3o όρισμα, ονόματα αρχείων) 4
Regular Expressions in Text pattern Μπορούμε στην grep να δώσουμε αντί για τη λέξη ένα pattern κειμένου που θέλουμε να βρεθεί. Π.χ. να βρεθούν όλες οι λέξεις µε 4 γράμματα που αρχίζουν από d, ή αυτές που έχουν 6 ψηφία κτλ. (το αποτέλεσμα θα είναι πάντα γραµµές που κάνουν match το pattern). Αυτά τα patterns λέγονται κανονικές εκφράσεις (Regular Expressions) και χρησιμοποιούν κάποιους χαρακτήρες µε ειδικό νόημα. Χρησιμοποιούμε την εντολή egrep ή την grep με παράμετρο -Ε. Αν το pattern που αναζητούμε είναι μία λίστα χαρακτήρων που περικλείεται από αγκύλες [] (bracket expression) τότε αναζητεί οποιονδήποτε χαρακτήρα της λίστας. Αν ο πρώτος χαρακτήρας της λίστας είναι ο ^ τότε αναζητεί χαρακτήρες που δεν υπάρχουν στη λίστα. Για παράδειγμα, η κανονική έκφραση [0123456789] αντιστοιχεί σε οποιονδήποτε μονοψήφιο αριθμό. Όταν μέσα στις αγκύλες έχουμε δύο χαρακτήρες που χωρίζονται από μια παύλα (-) αναζητούνται όλοι οι χαρακτήρες που βρίσκονται μεταξύ των δύο χαρακτήρων. Για παράδειγμα, αν γράψουμε [a-d] ισοδυναμεί με [abcd]. Οι χαρακτήρες ^ και $ είναι μεταχαρακτήρες που αντιστοιχούν σε οποιουσδήποτε χαρακτήρες στην αρχή και στο τέλος μιας γραμμής. Τα σύμβολα \< και \> που αντιστοιχούν σε οποιουσδήποτε χαρακτήρες στην αρχή και στο τέλος μιας λέξης. Ο χαρακτήρας τελεία. αντιστοιχεί σε οποιοδήποτε χαρακτήρα. Ένα regular expression μπορεί να ακολουθείτε από έναν ή περισσότερους τελεστές επανάληψης:? Ο χαρακτήρας που προηγείται είναι προαιρετικός και υπάρχει το πολύ μία φορά. * Ο χαρακτήρας που προηγείται υπάρχει καμία ή περισσότερες φορές. + Ο χαρακτήρας που προηγείται υπάρχει μία ή περισσότερες φορές. {n} {n,} Ο χαρακτήρας που προηγείται υπάρχει ακριβώς n φορές. Ο χαρακτήρας που προηγείται υπάρχει ακριβώς n ή περισσότερες φορές. {n,m} Ο χαρακτήρας που προηγείται υπάρχει τουλάχιστον n φορές αλλά το πολύ m φορές. 5
Για αναλυτική περιγραφή των regular expressions και δυνατότητα online δοκιμών, μεταβείτε σε αυτή την ιστοσελίδα: http://www.regexr.com/ Παραδείγματα: 1. egrep "support help windows" myfile.txt Αναζητά τις λέξεις support help και windows στο αρχείο myfile.txt. 2. egrep '^[a-za-z]$' myfile.txt Αναζητά τις γραμμές στο αρχείο myfile.txt που ξεκινούν και τελειώνουν με ένα οποιοδήποτε γράμμα. 3. egrep '^begin end$' myfile.txt Αναζητά τις γραμμές στο αρχείο myfile.txt που ξεκινούν με τη λέξη 'begin' ή τελειώνουν με τη λέξη 'end'. 4. Έστω ότι έχουμε το αρχείο file1 με το παρακάτω περιεχόμενο: ra la la tra traaatratra tra tra tra tra Eντολή Εξήγηση Αποτέλεσµα-γραµµές egrep 't{1,3}' file1 1..3 εµφανίσεις του t όλες και η 3η egrep 'tra{1,3}' file1 tr και 1..3 εµφανίσεις του a egrep 'tra{3}' file1 tr και 3 επαναλήψεις του a egrep 'tra {1,3}' file1 tra, 1..3 εµφανίσεις του κενoύ όλες οι γραµµές 2η γραµµή 3η (1η 2η δεν έχει κενό) egrep '(tra ){3}' file1 3 εµφανίσεις του tra κενό 3η oµαδοποίηση µε () 6
Ασκήσεις 1. Δημιουργήστε ένα νέο έγγραφο με όνομα Επίθετο.txt, γράψτε μέσα ένα κείμενο (ότι θέλετε), τουλάχιστον 5 γραμμών και αποθηκεύστε το. TIP: Φροντίστε έτσι ώστε οι γραμμές που γράφετε στα κείμενά σας να μην ξεπερνούν τους 80 χαρακτήρες (μαζί με τα κενά). Αυτό είναι ένα unofficial standard για να είναι ευανάγνωστες οι γραμμές και να μην κόβονται όταν ανοίγετε το κείμενο με τον editor. (σε fullscreen) 2. Ανοίξτε το κείμενο Επίθετο.txt επιλέξτε τις δυο πρώτες γραμμές και κάντε τις επικόλληση στο τέλος (χωρίς να τις διαγράψετε). Αποθηκεύστε και κλείστε το κείμενο. 3. Ανοίξτε το κείμενο Επίθετο.txt και αφαιρέστε τις 2 τελευταίες γραμμές που προσθέσατε πριν. Tip: Ο nano δεν έχει λειτουργία διαγραφής γραμμής. Μπορείτε να χρησιμοποιείστε το keystroke Cut για να κόψετε τις γραμμές και μετά να αποθηκεύσετε και να κλείσετε το έγγραφο. Λάβετε υπόψιν σας πως αν το έγγραφο παραμείνει ανοιχτό, τότε ο nano κρατά στην μνήμη τις γραμμές που έχετε κόψει ακόμη και αν κάνετε copy κάποια άλλη. Δεν λειτουργεί δηλαδή σαν το clipboard. Οπότε σε ενδεχόμενο paste, θα κάνει όλες τις γραμμές paste ταυτόχρονα. 4. Για κάθε κανονική έκφραση που υπάρχει στην πρώτη στήλη του πίνακα που ακολουθεί να χρησιμοποιήσετε την εντολή egrep για να βρείτε ποιοι συνδυασμοί χαρακτήρων από εκείνους που ακολουθούν θα εντοπισθούν. to hot to toad stool Top t.n tin stun nation stony tnuch a[o-t]. art act task tort At Για να το δοκιμάσετε δημιουργήστε 3 αρχεία (file1, file2,file3). Στο file1 γράψτε χρησιμοποιώντας τον nano τις γραμμές: hot to 7
toad stool Και δοκιμάστε την εντολή grep 'to' file1 Αντίστοιχα προφανώς και για τα υπόλοιπα αρχεία. Στην εντολή grep, μπορείτε να χρησιμοποιήστε το option --color. τότε χρωματίζεται το σημείο κάθε γραμμής που ταίριαξε στην κανονική έκφραση. 5. Υποθέστε ότι έχετε το παρακάτω αρχείο κειμένου (tel.txt) που περιέχει τον τηλεφωνικό κατάλογο μιας εταιρείας. Κάθε γραμμή περιέχει : επίθετο, κόμμα, κενό διάστημα, το όνομα, κόμμα, κενό διάστημα, τηλέφωνο. Francis, John, 5-3871 Wong, Fred, 4-4123 Jones, Thomas, 1-4132 Jones, Tom, 5-4122 Salazar, Richard, 5-2522 S, R, 6-3433 Να εμφανίσετε όλες τις γραμμές (χρησιμοποιώντας εντολές egrep και κανονικές εκφράσεις) : a) Με επίθετο που ξεκινά από M έως Z b) Με επίθετο μήκους 7 χαρακτήρων c) Με όνομα που αρχίζει από J ή F d) Που δεν περιέχουν τα γράμματα J ή W e) Με αριθμό τηλεφώνου που αρχίζει από 1 και τελειώνει σε 2. f) Με αριθμό τηλεφώνου που ΔΕΝ τελειώνει σε 22. g) Με επίθετο που ξεκινά από M έως Z και αριθμό που τελειώνει με 1 ή 2. Στην επόμενη σελίδα ακολουθούν οι λύσεις των ασκήσεων. Προσπαθήστε να τις λύσετε πριν τις δείτε! 8
ΛΥΣΕΙΣ ΑΣΚΗΣΕΩΝ: a) egrep "^[Μ-Ζ]" tel.txt b) egrep "^[Α-Ζ][a-z]{6}" tel.txt c) egrep "*., [J F]" tel.txt d) egrep "^[^JW]*$" tel.txt e) egrep "\<1.*2\>" tel.txt f) egrep -v "22$" tel.txt g) egrep "^[M-Z].*[1 2]$" tel.txt 9