Manipolazione del testo Sintassi delle espressioni regolari Alcuni programmi di manipolazione del testo come &man.grep.1;, &man.egrep.1;, &man.sed.1;, &man.awk.1; e &man.vi.1; consentono di ricercare uno schema (pattern) piuttosto che una stringa fissa. Questi schemi testuali sono conosciuti come espressioni regolari. Si può formare un'espressione regolare combinando caratteri normali con caratteri speciali, anche conosciuti come meta-caratteri, secondo le successive regole. Con queste espressioni regolari si può confrontare uno schema su dati testuali. Le espressioni regolari si presentano in tre diverse forme: Ancoraggi legano lo schema a una posizione sulla linea Serie di caratteri indicano un carattere in una singola posizione Modificatori specificano quante volte ripetere l'espressione precedente Segue la sintassi delle espressioni regolari. Alcuni programmi accettano tutte queste sintassi, altri ne accettano solo alcune: . indica un singolo carattere eccetto quello di newline * indica zero o più istanze del singolo carattere (o meta-carattere) che lo precede [abc] indica un carattere tra quelli racchiusi [a-d] indica un carattere tra quelli compresi nel range [^exp] indica un carattere tra quelli non inclusi nell'espressione ^abc l'espressione regolare deve iniziare all'inizio della linea (Ancoraggio) abc$ l'espressione regolare deve finire alla fine della linea (Ancoraggio) \ tratta il carattere successivo letteralmente. Viene normalmente usato per mantenere inalterato il significato di un carattere speciale come . e *. \{n,m\} confronta l'espressione regolare precedente un numero minimo n di volte e un numero massimo m di volte (n e m possono assumere valori tra 0 e 255). I simboli \{ e \} dovrebbero essere intesi come singoli operatori. In questo caso il simbolo \ che precede le parentesi non è il carattere di escape, ma assume un nuovo significato. \<abc\> confronta l'espressione regolare racchiusa trattandola come una singola parola. I limiti della parola sono definiti iniziando con un newline o qualche altra cosa, eccetto una lettera, una cifra o un underscore ( _ ), e finendo con la stessa cosa o con un carattere di fine linea. Ancora, i simboli \< e \> dovrebbero essere intesi come singoli operatori. \(abc\) salva lo schema racchiuso in un buffer. Possono essere salvati per ogni linea fino a nove schemi. È possibile riferirsi a questi schemi tramite la combinazione di caratteri \n. Ancora una volta i simboli \( e \) dovrebbero essere intesi come singoli operatori. \n dove n varia tra 1 e 9. Confronta l'n-sima espressione precedentemente salvata per la linea corrente. Le espressioni sono numerate partendo da sinistra. Il simbolo \n dovrebbe essere inteso come un singolo operatore. & mostra lo schema di ricerca precedente (usato al posto della stringa) Ci sono alcuni meta-caratteri usati solamente da &man.awk.1; e &man.egrep.1;. Questi sono: + confronta una o più delle espressioni precedenti (a questo simbolo) ? confronta zero o alcune delle espressioni precedenti (a questo simbolo) | separatore. Confronta sia l'espressione precedente (a questo simbolo) sia quella seguente ( ) raggruppa le espressioni regolari all'interno delle parentesi e applica una serie di confronti Alcuni esempi di espressioni regolari comuni sono: espressione regolare indica cat la stringa cat .at alcune occorrenze di un carattere precedente ad at, come cat, rat, mat, bat, fat, hat xy*z alcune occorrenze di un x, seguite da zero o più y e seguite da una z. ^cat cat all'inizio della linea cat$ cat alla fine della linea \* alcune occorrenze di un asterisco [cC]at cat o Cat [^a-zA-Z] alcune occorrenze di caratteri non alfabetici [0-9]$ alcune linee che finiscono con un numero [A-Z][A-Z]* una o più lettere maiuscole [A-Z]* zero o alcune lettere maiuscole (in altre parole, qualcosa) Comandi di manipolazione del testo Comandi di manipolazione del testo Comando/Sintassi Cosa fa awk/nawk [opzioni] file esamina gli schemi (pattern) all'interno di un file ed elabora i risultati grep/egrep/fgrep [opzioni] 'stringa di ricerca' file ricerca nell'argomento (in questo caso probabilmente un file) tutte le occorrenze della stringa di ricerca e le elenca sed [opzioni] file editor di flusso per manipolare file da uno script o da linea di comando
grep Questa sezione fornisce un'introduzione all'uso delle espressioni regolari con &man.grep.1;. L'utility &man.grep.1; viene usata per ricercare espressioni regolari comuni che si presentano nei file Unix. Le espressioni regolari, come quelle viste in precedenza, sono meglio specificate all'interno di apostrofi (o caratteri di quoting singoli) quando usate con l'utility &man.grep.1;. L'utility &man.egrep.1; fornisce una capacità di ricerca attraverso un set esteso di meta-caratteri. La sintassi dell'utility &man.grep.1;, alcune delle possibili opzioni e alcuni semplici esempi sono mostrati di seguito. Sintassi grep [opzioni] expreg [file] Opzioni generali ignora la differenza tra caratteri maiuscoli e minuscoli riporta solamente la somma del numero di linee contenenti le corrispondenze, non le corrispondenze stesse inverte la ricerca, visualizzando solo le linee senza corrispondenza mostra un numero di linea insieme alla linea su cui è stata trovata una corrispondenza lavora in silenzio, riportando solo lo stato finale: 0, per corrispondenze trovate 1, per nessuna corrispondenza 2, per errori elenca i nomi dei file, ma non le linee, nei quali sono state trovate corrispondenze Esempi: Si consideri il seguente file: {Unix prompt 5} cat num.list 1 15 fifteen 2 14 fourteen 3 13 thirteen 4 12 twelve 5 11 eleven 6 10 ten 7 9 nine 8 8 eight 9 7 seven 10 6 six 11 5 five 12 4 four 13 3 three 14 2 two 15 1 one Ecco alcuni esempi di &man.grep.1; usando tale file. Nel primo si ricerca il numero 15: {Unix prompt 6} grep '15' num.list 1 15 fifteen 15 1 one Ora si usa l'opzione per contare il numero di linee che corrispondono al precedente criterio di ricerca: {Unix prompt 7} grep -c '15' num.list 2 Qui la ricerca è più generale: si selezionano tutte le linee che contengono il carattere 1 seguito da un 1 o un 2 o un 5: {Unix prompt 8} grep '1[125]' num.list 1 15 fifteen 4 12 twelve 5 11 eleven 11 5 five 12 4 four 15 1 one Ora si ricercano tutte le linee che iniziano con uno spazio: {Unix prompt 9} grep '^ ' num.list 1 15 fifteen 2 14 fourteen 3 13 thirteen 4 12 twelve 5 11 eleven 6 10 ten 7 9 nine 8 8 eight 9 7 seven Ora tutte le linee che non iniziano con uno spazio: {Unix prompt 10} grep '^[^ ]' num.list 10 6 six 11 5 five 12 4 four 13 3 three 14 2 two 15 1 one L'ultimo esempio può anche essere realizzato usando l'opzione insieme all stringa di ricerca originale, esempio: {Unix prompt 11} grep -v '^ ' num.list 10 6 six 11 5 five 12 4 four 13 3 three 14 2 two 15 1 one Ora si ricercano tutte le linee che iniziano con carattere compreso tra 1 e 9: {Unix prompt 12} grep '^[1-9]' num.list 10 6 six 11 5 five 12 4 four 13 3 three 14 2 two 15 1 one In questo esempio si ricercano alcune istanze di t seguite da zero o alcune occorrenze di e: {Unix prompt 13} grep 'te*' num.list 1 15 fifteen 2 14 fourteen 3 13 thirteen 4 12 twelve 6 10 ten 8 8 eight 13 3 three 14 2 two In questo esempio si ricercano alcune istanze di t seguite da una o alcune occorrenze di e: {Unix prompt 14} grep 'tee*' num.list 1 15 fifteen 2 14 fourteen 3 13 thirteen 6 10 ten Si può prendere il proprio input da un programma, anzichè da un file. Qui si riportano alcune linee di output del comando &man.who.1; che iniziano con la lettera l. {Unix prompt 15} who | grep '^l' lcondron ttyp0 Dec 1 02:41 (lcondron-pc.acs.) sed L'editor di flusso non interattivo &man.sed.1; manipola un flusso di input, linea per linea, creando specifici cambiamenti e mandando il risultato su standard output. Sintassi sed [opzioni] comando_di_editing [file] Il formato per i comandi di editing è: [indirizzo1[,indirizzo2]] [funzione] [argomenti] dove gli indirizzi sono facoltativi e possono essere separati dalla funzione tramite spazi o tab. La funzione è obbligatoria. L'argomento può essere facoltativo o obbligatorio a seconda della funzione usata. Gli indirizzi di linea numerati sono numeri decimali di linea che partono dalla prima linea di input e si incrementano di uno per ogni linea. Se vengono stabiliti più file di input il contatore continua cumulativamente attraverso i file. L'ultima linea di input può essere specificata con il carattere $. Gli indirizzi di contesto sono schemi di espressioni regolari racchiusi tra caratteri di slashe (/). I comandi possono avere 0, 1 o 2 indirizzi separati da virgola con i seguenti effetti: # indirizzi linee considerate 0 tutte le linee di input 1 solamente le linee che corrispondono agli indirizzi specificati 2 dalla prima linea che corrisponde al primo indirizzo fino alla linea che corrisponde al secondo indirizzo, inclusa. Il processo viene ripetuto per le linee interne. Le funzioni di sostituzione permettono di ricercare contesti e sono specificate nella forma: s/schema_espressione_regolare/stringa_di_rimpiazzo/flag e possono essere quotate con caratteri di quoting singoli (') se sono specificate opzioni o funzioni aggiuntive. Questi schemi sono identici agli indirizzi di contesto, eccetto che, mentre questi sono normalmente chiusi tra slashe (/), nelle funzioni sono permessi alcuni normali caratteri per specificare i delimitatori, oltre a newline e spazio. La stringa di rimpiazzo non è uno schema di espressione regolare; qui i caratteri non hanno significati speciali, fatta eccezione di: & che sostituisce tale simbolo con la stringa schema_espressione_regolare \n sostituisce tale simbolo con l'n-esima stringa corrispondente a schema_espressione_regolare chiusa tra una coppia di '\(','\)' Questi caratteri speciali possono essere messi in escape con il carattere backslash (\) per rimuovere il loro significato speciale. Opzioni generali script di editing non stampa l'output di default, ma solamente quelle linee specificate dalle funzioni p o s///p prende lo script di editing dal file specificato Alcune valide flag per le funzioni sostitutive sono: cancella lo schema sostituzione globale dello schema stampa le linee Esempi: Questo esempio modifica tutte le accidentali virgole (,) in una virgola seguita da uno spazio (, ) quindi crea l'output: &prompt.user; cat filey | sed s/,/,\ /g Il seguente esempio rimuove tutte le accidentali Jr precedute da uno spazio (Jr) all'interno del file filey: &prompt.user; cat filey | sed s/\ Jr//g Per realizzare operazioni multiple sull'input, si precede ogni operazione con l'opzione (edit) e si quota la stringa. Ad esempio, per filtrare le linee contenenti Date: e From: e rimpiazzarle senza i due punti (:): &prompt.user; sed -e 's/Date: /Date /' -e 's/From: /From /' Per visualizzare solamente le linee del file che iniziano con Date: e includerne una che inizia con Name:: &prompt.user; sed -n '/^Date:/,/^Name:/p' Per stampare solamente le prime 10 linee dell'input (un rimpiazzo di &man.head.1;): &prompt.user; sed -n 1,10p awk, nawk, gawk &man.awk.1; è un linguaggio di elaborazione e ricerca di schemi. Il suo nome deriva dalle ultime iniziali dei tre autori: Alfred. V. Aho, Peter. J.Weinberger e Brian. W. Kernighan. nawk è un nuovo &man.awk.1;, una nuova versione del programma e &man.gawk.1; è il gnu &man.awk.1;, da parte della Free Software Foundation. Ogni versione è leggermente differente. Qui ci si limiterà ad illustrare semplici esempi che potrebbero andar bene per tutte le versioni. In alcuni sistemi operativi &man.awk.1; è in realtà nawk. &man.awk.1; ricerca schemi nel suo input e realizza le operazioni specificate su ogni linea o sui campi di linea che contengono tali schemi. Le espressioni dello schema di confronto per &man.awk.1; possono essere specificate sia attraverso linea di comando, sia inserendole in un file e usando l'opzione . Sintassi awk programma [file] dove programma è composto da uno o più dei seguenti campi: schema { azione } Ogni linea di input viene verificata con lo schema di confronto insieme alla specifica azione che bisogna realizzare per ogni corrispondenza trovata. Questo continua attraverso la completa sequenza di schemi, quindi la prossima linea di input viene verificata. L'input è diviso tra record e campi. Il separatore di record di default è newline e la variabile NR tiene il conto dei record. Il separatore di campo di default è uno spazio bianco, spazi e tab, e la variabile NF tiene il conto dei campi. I separatori di input del campo, FS e del record, RS, possono essere settati in qualsiasi momento per farli corrispondere a singoli caratteri specifici. I separatori di output del campo, OFS e del record, ORS, possono essere modificati, se si desidera, con singoli caratteri specifici. $n, dove n è un intero, viene usato per rappresentare l'n-esimo campo di un record di input, mentre $0 rappresenta l'intero record di input. BEGIN e END sono speciali schemi che vengono verificati rispettivamente all'inizio dell'input, prima che il primo campo sia letto e alla fine dell'input, dopo che l'ultimo campo è stato letto. La stampa è permessa attraverso l'istruzione print e l'istruzione per la stampa formattata printf. Gli schemi (pattern) possono essere espressioni regolari, espressioni aritmetiche relazionali, espressioni di valutazione di stringhe e combinazioni buleane di alcune di queste. In quest'ultimo caso gli schemi possono essere combinati con i seguenti operatori buleani, usando le parentesi per definire le combinazioni: || or && and ! not La separazione di schemi con virgole definisce un range in cui lo schema è applicabile, esempio: /primo/,/ultimo/ seleziona tutte le linee partendo con quella che contiene primo e continuando inclusivamente fino alla linea che contiene ultimo. Per selezionare le linee da 15 a 20 si usa il seguente schema: NR==15 , NR==20 Le espressioni regolari devono essere chiuse tra slashe (/) e i meta-caratteri possono essere messi in escape con il carattere di backslash (\). Le espressioni regolari possono essere raggruppate con gli operatori seguenti: | per alternative separate + una o più ? zero o una Un confronto di espressione regolare può essere specificato con: ~ contiene l'espressione !~ non contiene l'espressione Quindi il programma: $1 ~ /[Ff]rank/ è vero se il primo campo, $1, contiene "Frank" o "frank" dovunque all'interno del campo. Per confrontare un campo identico a "Frank" o "frank" si usa: $1 ~ /^[Ff]rank$/ Le espressioni relazionali sono permesse usando i seguenti operatori relazionali: < minore di <= minore o uguale a = = uguale a >= maggiore o uguale a != non uguale a > maggiore di Non si può conoscere su due piedi se le variabili sono stringhe o numeri. Se nessun operando è riconosciuto per essere un numero, sono realizzati confronti di stringhe. Altrimenti, viene realizzata una comparazione numerica. In mancanza di informazioni per il contrario, viene realizzata una comparazione di stringa, così questa: $1 > $2 verrà valutata con valori di tipo stringa. Per assicurarsi una valutazione numerica, costruire qualcosa simile a: ( $1 + 0 ) > $2 Le funzioni matematiche exp, log e sqrt sono di tipo built-in. Altre funzioni built-in sono: index(s,t) ritorna la posizione della stringa s dove si presenta il primo t o 0 se non esiste lenght(s) ritorna la lunghezza della stringa s substr(s,m,n) ritorna l'n-esimo carattere della sottostringa di s, iniziando dalla posizione m Gli array sono dichiarati automaticamente quando vengono usati, per esempio: arr[i]=$1 assegna il primo campo del corrente record di input all'i-esimo elemento dell'array. Le espressioni di controllo di flusso if-else, while e for sono permesse con la sintassi del C: for (i=1; i <= NF; i++) {azioni} while (i<=NF) {azioni} if (i<NF) {azioni} Opzioni generali legge i comandi dal file specificato usa il carattere c come il carattere di separatore di campo Esempi: &prompt.user; cat filex | tr a-z A-Z | awk -F: '{printf("7R %-6s %-9s %-24s \n",$1,$2,$3)}' > upload.file effettua cat su filex, che è formattato in questo modo: nfb791:99999999:smith 7ax791:999999999:jones 8ab792:99999999:chen 8aa791:999999999:mcnulty cambiando tutti i caratteri minuscoli in caratteri maiuscoli con l'utility &man.tr.1; e formattando il file come mostrato di seguito, il quale viene scritto nel file upload.file 7R NFB791 99999999 SMITH 7R 7AX791 999999999 JONES 7R 8AB792 99999999 CHEN 7R 8AA791 999999999 MCNULTY