Guida Linux: i filtri e le espressioni regolariI filtriI filtri sono comandi che leggono dei dati, li elaborano ed inviano in output il risultato. I dati possono provenire da file, dispositivi o possono essere l'output di altri comandi. L'output di un filtro e' generalmente l'output standard (il video) ma puo' essere rediretto verso un file, un dispositivo od un altro comando che puo' essere a sua volta un filtro. Un esempio di filtro e' il comando cat (da conCATenate). Il comando cat accetta in input dei dati e li visualizza a video. Se non viene specificato l'input, il comando cat accetta i dati dall'input standard (la tastiera). Percio' il comando cat > lettera si mette in attesa di dati dalla tastiera e al termine del flusso li scrive all'interno del file lettera:
cat > lettera Per terminare l'input da tastiera occorre premere la combinazione dei tasti CTRL e D che invia il carattere di fine file. I filtri head (testa) e tail (coda) servono per visualizzare le prime righe di un testo (head) o le ultime righe (tail). Ad esempio il comando head -2 visualizza le prime due righe di un testo:
cat lettera mentre il comando tail -2 lettera visualizza le ultime due:
cat lettera Altri esempi di filtri sono i comandi wc (Word Count) spell e sort. Il comando wc conta il numero di righe, parole e caratteri (inclusi i caratteri di fine riga) presenti all'interno di un file. Il comando spell legge un file e produce in output tutte le parole errate che trova (utilizzando il dizionario inglese). Il comando sort legge un file e lo riproduce in output in modo ordinato. Un altro esempio di filtri sono i comandi grep ed fgrep. Tali comandi ricercano una stringa all'interno di un file. Ad esempio, se all'interno di una directory con molti file esiste un file al cui interno e' presente la stringa 'pippo' ma non ricordiamo piu' il nome di tale file, e' possibile individurarlo utilizzando il comando grep. Il comando grep accetta due argomenti, il primo e' la stringa da ricercare, il secondo e' un elenco di file. Per specificare l'elenco di file e' anche possibile usare i caratteri speciali come '*'. Esempio:
cat lettera se la stringa da ricercare contiene degli spazi occorre scriverla tra apici altrimenti il comando grep interpretera' lo spazio come un delimitatore considerando gli altri argomenti successivi al primo come nomi di file all'interno dei quali effettuare la ricerca. Esempio:
cat lettera qualora non fossero stati digitati gli apici il comando grep avrebbe ricercato la stringa 'caro' all'interno dei file: amico, lettera e documento. Occorre ricordarsi che Linux e' case sensitive, cioe' fa differenza tra caratteri maiuscoli e caratteri minuscoli:
cat lettera il comando grep in questo caso ricerca la stringa 'caro amico' all'interno dei file lettera e documento ma non produce alcun risultato in quanto 'Caro amico' e 'caro amico' sono due stringhe diverse. Per effettuare una ricerca senza badare ai caratteri maiuscoli o minuscoli occorre usare l'opzione -i: grep -i 'caro amico' lettera documento. Il comando grep puo' anche funzionare al contrario, e' possibile cioe' ricercare tutte le righe che non contengono una data stringa. A tale scopo occorre usare l'opzione -v. Il filtro fgrep e' piu' veloce di grep e puo' cercare contemporaneamente piu' stringhe nei file. Tale comando a differenza di grep non accetta pero' le espressioni regolari. Altri filtri utili sono i comandi diff e sed. Il comando diff permette di confrontare due file per visualizzare le righe differenti. Il comando diff produce in output le righe che risultano differenti, evidenziando quelle del primo file con il carattere '<' e quelle del secondo file con il carattere '>'. Il comando diff inoltre indica le operazioni che occorre effettuare per rendere i due file uguali. Sono possibili 3 operazioni: a, d o c. L'operazione a significa aggiungere, l'operazione d significa cancellare e l'operazione c significa sostituire. Un esempio chiarira' il funzionamento di diff:
cat frutta cioe': sostituire la terza riga del primo file con le righe dalla terza alla quinta del secondo file. La riga del primo file da sostiture e' < banane le righe del secondo file sono > carote, > pomodori e > cavoli. Per ignorare le differenze tra caratteri maiuscoli e caratteri minuscoli e' possibile usare l'opzione -i. Ovviamente e' possibile reindirizzare l'output del comando diff all'interno di un file: diff frutta fruttaeverdura > differenze. Esistono molti altri filtri come join, cut, paste, egrep, comm, cmp, tee, sort, pr, sed...tra questi un filtro molto usato e' il comando sed. Sed sta per Stream EDitor, cioe' editor di flusso: si tratta in sostanza di un editor di riga. Il comando sed accetta in input un comando di editing ed un elenco di file e genera in output una copia modificata di tali file. Esempio:
cat frutta nell'esempio appena visto il comando sed cancella la terza riga dal file frutta. Il comando sed puo' effettuare varie operazioni di editing (inserimento, cancellazione, sostituzione etc.): per conoscere l'elenco completo delle operazioni di editing effettuabili consultare la relativa pagina di man (man sed). Le espressioni regolariUna espressione regolare e' una stringa che contiene caratteri speciali. I caratteri speciali delle espressioni regolari pero' sono diversi dai caratteri speciali della shell: i primi consentono di effettuare ricerche all'interno di un testo mentre gli altri operano sui nomi di file. Le espressioni regolari possono essere utilizzate da molti filtri come ad esempio grep, sed e awk. I caratteri speciali sono l'accento circonflesso, il dollaro, l'asterisco, il punto e le parentesi quadre. Il segno ^ (accento circonflesso) ed il segno $ (dollaro) indicano rispettivamente l'inizio della riga e la fine della riga. Per ricercare tutte le righe all'interno di un testo che iniziano con la parola 'pippo' occorre definire una espressione regolare in questo modo: ^pippo. Al contrario per ricercare all'interno di un testo tutte le righe che terminano con al stringa 'pluto' occorre definire una espressione regolare in quest'altro modo: pluto$. Vediamo un esempio:
cat testo il primo comando grep ricerca le righe che iniziano per 'che' mentre il secondo ricerca le righe che terminano con 'lari. Per ricercare le righe che contengono unicamente una determinata stringa si possono combinare i caratteri ^ e $ insieme in questo modo: ^stringa$, dove stringa e' la parola da ricercare. Se infine si vogliono ricercare tutte le righe vuote si puo' costruire una espressione regolare che contenga unicamente i caratteri ^ e $. Esempio:
cat testo Le espressioni regolari possono essere usate anche combinando piu' comandi attraverso le pipe: ls -l | grep '^d' i comandi precedenti elencano i file contenuti all'interno della directory corrente e di questi file estraggono solo quelli che iniziano per 'd', cioe' tutti i file che sono directory. Infatti il comando ls -l elenca tutti i file in modalita' estesa (-l sta per long). Ogni riga prodotta in output dal comando ls -l contiene un trattino '-' per i file comuni e una 'd' per le directory: tale output viene passato tramite pipe al comando grep che ricerca solo le righe che iniziano per 'd'. Il risultato finale e' l'elenco delle directory contenute all'interno della directory corrente. Un altro carattere speciale e' il punto: tale simbolo significa qualsiasi carattere. Ad esempio la stringa 'a.a' individua tutte le stringhe che iniziano per a, terminano per a e contengono un qualsiasi altro carattere. Le stringhe che soddisfano questa espressione regolare possono essere: ala, ara, a+a, ava, aka e via dicendo. E' possibile usare piu' punti, ad esempio l'espressione regolare: bar.. trova tutte le stringhe che iniziano per bar e contengono 2 altri caratteri qualsiasi. Le stringhe che soddisfano tale espressione possono essere: barca, barza, barone, baronetto e via dicendo. Il carattere '*' posto all'interno di una espressione regolare trova sequenze di 0 o piu' caratteri uguali al carattere che lo precede. Ad esempio bo* permette di trovare stringhe come boomerang, bossolo, boa e cosi' via. L'ultima serie di caratteri speciali usabili nelle espressioni regolari sono le parentesi quadre. Le parentesi quadre permettono di specificare un particolare carattere o una particolare sequenza di caratteri. Vediamo un esempio: gruppo[145] l'espressione regolare appena vista individua tutte le stringhe che iniziano per gruppo e terminano con 1, 4 o 5. Le stringhe gruppo1, gruppo2 e gruppo4 soddisfano i criteri ma la stringa gruppo9 o la stringa gruppo6 non soddisfano i criteri e pertanto non verranno individuate. La stringa gruppo2 soddisfa i criteri ma la stringa Gruppo2 non li soddisfa. Infatti 'gruppo2' e 'Gruppo2' sono due stringhe diverse. E' possibile pero' individuare entrambe le stringhe in questo modo: [gG]gruppo[2] E' possibile effettuare delle ricerche procedendo in senso inverso, cioe' individuando non tanto le stringhe da trovare ma bensi' le stringhe che non devono essere trovate. Per effettuare cio' e' possibile usare il simbolo '^' per escludere alcuni caratteri dalla ricerca. L'accento circonflesso si deve trovare tra la prima parentesi quadra ed il primo carattere all'interno delle parentesi quadre: gruppo[^3456789] l'espressione regolare esposta individua le stringhe gruppo1 e gruppo2 ma non le stringhe gruppo3, gruppo4 o gruppo9, in quanto terminano con un carattere che non deve essere presente: tutte le stringhe che terminano con 3,4,5,6,7,8 o 9 non verranno individuate. Se viene posto un trattino all'interno delle parentesi quadre viene definita una sequenza di caratteri. Ad esempio l'espressione regolare [A-Z] individua tutti i caratteri dell'alfabeto maiuscoli mentre [a-z] individua quelli minuscoli. Allo stesso modo l'espressione regolare [0-9] individua tutti i numeri da 0 a 9. Per includere anche il trattino nella ricerca, occorre usare il carattere '\' come carattere di quotazione: [0-9\-]. Tale espressione individua le stringhe che terminano con un numero o con un trattino. E' possibile combinare tutti questi caratteri speciali insieme per costruire delle stringhe di ricerca particolarmente efficaci. Ad esempio la stringa [0-9][0-9]* significa qualsiasi stringa che inizia con un numero e che termina con uno o piu' numeri: in sostanza vengono individuate solo stringhe numeriche. Allo stesso modo la stringa [A-Z][A-Z]* individua qualsiasi stringa composta da caratteri maiuscoli. Esempio: I PC IBM sono stati i primi personal computer della storia e sono nati nel 1981 all'interno della riga esposta, l'espressione regolare [A-Z][A-Z]* individua le stringhe PC ed IBM mentre l'espressione regolare [0-9][0-9]* individua la stringa 1981. Le espressioni regolari possono essere particolarmente efficaci: ls -l | grep '^......r.x' i comandi esposti permettono di individuare tutti i file per i quali tutti gli altri utenti (proprietario e gruppo esclusi) posseggano i permessi di lettura ed esecuzione. Ecco un riepilogo dei caratteri speciali utilizzabili all'interno di espressioni regolari:
^ inizio riga Infine esistono alcuni comandi che accettano anche altri caratteri come ad esempio il comando egrep. Il comando egrep infatti accetta anche i simboli: |, (), + e ?. Il simbolo | rappresenta l' OR logico, cioe' permette di indicare delle stringhe alternative. Ad esempio 'frutta|verdura' individua sia la parola frutta che la parola verdura. Le parentesi permettono di concatenare piu' stringhe: (latte(intero|scremato). Il carattere + ricerca una o piu' ripetizioni del carattere precedente, ad esempio o+ individua una o piu' o come ad esempio zoo, boomerang e via dicendo. Il carattere ? infine, individua 0 o 1 istanze del carattere precedente.
Copyright (c) 2002 M. Silvestri |