In questa prima parte della guida sono trattati i concetti di ciclo di esecuzione, di adress e di istructions; sono presentati i vari tipi di adress utilizzabili e la maggior parte delle istructions di manipolazione del testo.
Autore | Giacomo Mengucci |
---|---|
Licenza | FDL |
Ultimo Aggiornamento | 14/10/2007 |
SED è un editor di testo stream oriented: il programma legge una riga di testo alla volta, su di essa compie le operazioni di manipolazioni richieste ed infine restituisce la riga sullo standard output (lo standard output di norma è il monitor, ma tale flusso di output può essere rediretto verso un file).
SED usa le espressioni regolari (REGEXP) per selezionare le righe di testo su cui compiere le operazioni di manipolazione; le espressioni regolari sono dei modelli descrittivi sulla base dei quali sono ricercate sottostringhe di testo su una stringa ricevuta in input; tali modelli sono definiti attraverso una sorta di linguaggio che ha una propria sintassi e una propria semantica; la stringa di input può essere una riga di testo acquisita direttamente da un file o comunque derivante da una pipeline.
Per riga di testo si intende una sequenza di caratteri che si conclude con il carattere di terminazione, che per i sistemi unix è il newline \n.
Per stream di input si intende, metaforicamente, il flusso sequenziale di dati che provengono da una determinata fonte; il flusso può essere considerato, da un punto di vista logico e a seconda del contesto, come una sequenza di caratteri singoli, oppure come una sequenza di righe di testo; la fonte è normalmente un file o una pipeline.
Il modello di elaborazione del flusso di testo ad opera di SED èil seguente:
Il fatto che SED legga sempre tutte le righe, non vuol dire che su tutte le righe saranno eseguite le operazioni di manipolazione specificate.
SED, infatti, dà la possibilità di selezionare su quali righe ricevute in input eseguire le operazioni specificate. La selezione avviene attraverso i così detti adress. Gli adress sono di diversa natura e ciascuno sottointende un particolare modo di selezionare le righe.
L'adress più semplice è l'indicazione del numero di riga su cui compiere l'operazione; l'adress più versatile e potente è quello che fa uso delle espressioni regolari; in tal caso l'operazione viene eseguita solo sulle righe che hanno una corrispondenza con il modello definito attraverso l'espressione regolare.Le opzioni sono tutte facoltative. Lo script è il cuore del comando; in esso vengono indicati gli adress e le istructions sulla base dei quali processare ciascuna riga; filename è il nome del file di testo che deve essere processato.
SED, oltre che ricevere l'input da un file, può riceverlo da un'altro comando in una pipeline.
Lo script passato direttamente nella linea di comando deve essere racchiuso fra apici singoli; il primo argomento che non è un opzione deve essere uno script; l'opzione -e serve ad indicare in modo chiaro quale sia lo script o gli script da processare.
Oltre che passare gli script dalla linea di comando, essi si possono prima scrivere in un file separato e poi farli utilizzare da SED attraverso l'opzione -f.
Quando una riga viene processata con più script, si deve fare attenzione al fatto che il primo script può modificare la riga, cosicchè il secondo script non processerà la riga originariamente letta in myfile.txt, ma la riga modificata dal primo script; lo stesso discorso vale per gli script successivi: lo script n processerà la riga che può essere stata già modificata dagli script n-1, n-2 e così via.
La struttura logica dello script è molto semplice:
Adress rappresenta l'indirizzo che serve per selezionare le righe. Istructions rappresenta l'operazione da compiere sulle righe selezionate.
L'adress è facoltativo, se viene omesso l'istruzione sarà applicata ad ogni riga del file.
Le righe di testo processate da SED per mezzo degli script sono sempre inviate sullo standard output. (SED non modifica mai la sorgente di testo originaria)
In particolare ricevuta in input una riga, SED inizia a processarla con gli script; terminata tale attività, la riga viene immediatamente inviata allo standard output, indipendentemente dal fatto che l'applicazione degli script abbia determinato o meno una modifica della riga stessa.
In pratica SED invia allo standard output tutte le linee ricevute in input, senza distinguere fra righe modificate dopo l'applicazione degli script e righe non modificate dagli script.
Questo comportamento predefinito può essere modificato attraverso l'opzione -n; tale opzione sopprime l'output automatico e quindi SED non invia più le righe processate allo standard output.
Sopprimere l'output automatico non vuol dire che SED invia allo standard output solo le righe modificate dagli script, ma vuol dire che allo standard output saranno inviate solo quelle righe per le quali è ordinato in modo esplicito l'invio attraverso una istruction di stampa come p.
Il meccanismo di lettura riga per riga si fonda sul così detto pattern space.
Il pattern space è un buffer (spazio di memorizzazione) in cui la riga di input viene memorizzata in attesa di essere processata.
Le istruzioni contenute nei vari script agiscono proprio sulla riga che è stata memorizzata nel pattern space.
Se il primo script modifica la riga nel pattern space, il secondo script agirà sulla riga modificata dal primo script.
Applicati tutti gli script sulla riga nel pattern space, questa viene inviata sullo standard output e nel pattern space viene caricata la riga successiva.
L'insieme di tutte queste attività gestite direttamente da SED prende il nome di ciclo di esecuzione che può essere schematizzato come segue:
Conclusa l'attività n. 5, il ciclo ricomancia con l'attività n. 1, per cui SED riceve la riga successiva dallo stream di input; ogni riga dello stream di input ha, quindi, un proprio ciclo di esecuzione.
L'attività n. 3 è stata definita come applicare lo script sulla riga nel pattern space; questa definizione significa essenzialmente due cose:
L'adress di uno script serve per determinare se sulla riga caricata nel pattern space debba essere eseguito l'istructions dello script.
Le sequenze di caratteri caricate nel pattern space sono le righe di testo provenienti dallo stream di input.
Le righe di testo terminano con un newline.
I caratteri di newline finali, benchè facenti parte della riga di testo, non sono caricati sul pattern space.
Proprio perchè tale newline non è caricato nel pattern space, esso non influenza le verifiche di corrispondenza conseguenti alle espressioni regolari utilizzate negli script di SED.
Quando il pattern space è inviato, per qualsiasi causa, allo standard output, SED si preccupa di aggiungere nuovamente il newline finale.
L'adress numero di riga serve per selezionare una riga di testo secondo l'ordine sequenziale in cui è memorizzata sullo stream di input; l'ordine sequenziale è rappresentato da un numero intero che indentifica la posizione della riga nello stream di input.
Il modello astratto di tale tipo di adress è il seguente:
Il simbolo N va sostituito con un numero intero che identifica la riga.
Come si può notare l'istruction segue immediatamente, senza spazi, il numero di riga utilizzato per la selezione.
SED assegna il numero alle varie righe di testo provenienti dallo stream di input contando da 1.
Quando viene definito un adress di tipo espressione regolare, prima di applicare l'istructions sulla riga caricata nel pattern space, SED la confronta con l'espressione regolare dell'adress; solo se la corrispondenza è verificata, l'istructions viene eseguita.
La corrispondenza può dirsi verificata quando nella riga sul pattern space esiste una sottostringa conforme al modello regexp.
L'espressione regolare dell'adress è delimitata all'inzio e alla fine da un simbolo / (slash), a cui segue immediatamente, senza alcuno spazio separatore, l'istruction.
GNU SED ha introdotto alcuni modificatori particolari che agiscono sul modo in cui gli adress espressione regolare vengono valutati.
Il modificatore I (i
maiuscola), posto subito dopo il delimitatore / di chiusura, fa si che la verifica
di corrispondenza al modello regexp sia fatta senza tener
conto della differenza fra lettere minuscole e lettere
maiuscole.
L'istruction segue il simbolo I senza spazi separatori.
Tale modificatore agisce sul modo in cui i metacaratteri ^ e $ di una espressione regolare sono valutati in relazione ad un pattern space multi riga.
Per una spiegazione più dettagliata del funzionamento del modificatore M, si rimanda alla parte 2 del manuale, attualmente in corso di elaborazione, che tratta dei pattern space multi riga.
Con gli adress simbolici l'struction è eseguita solo sulla specifica riga selezionata secondo il significato proprio del simbolo utilizzato.
Il segnaposto S rappresenta il simbolo a cui SED assegna una particolare signficato selettivo.
Attualmente l'unico adress simbolico supportato dallo standard POSIX e da GNU SED è il $, che fa riferimento all'ultima riga dello stream di input.
Notare che gli indirizzi simbolici, come gli indirizzi numero di linea e a differenza degli indirizzi espressione regolare, non vanno delimitati da alcun carattere, per cui l'istruction segue immediatamente il simbolo dell'adress.
Un ulteriore tipologia di adress introdotta da GNU SED è il così detto adress di passo.
Con tale tipologia si indica il numero della riga da
selezionare per prima e poi si definisce un passo per le
selezioni successive, cioè si specifica quante righe SED deve
contare prima di procedere alla selezione di un ulteriore riga
dopo quella in precedenza selezionata.
Il conteggio relativo al passo inizia sempre sulla riga di
testo successiva a quella da ultimo selezionata.
Il simbolo N rappresenta il numero della riga di partenza, il simbolo ~ rappresenta un separatore obbligatorio ed il simbolo P rappresenta il passo per le selezioni successive.
É il caso di precisare che quando si utilizza un adress di passo, tutte le righe sono caricate nel pattern space, ma l'istruction sarà eseguita solo su quelle che presentano un numero d'ordine conforme al passo definito.
Un'altra funzionalità importante delle estensioni GNU è l'inversione della selezione, identificata dal simbolo !, posto come ultimo carattere dell'adress (subito prima dell'istruction).
L'adress serve per selezionare le righe su cui sarà applicata l'istruction; con l'inversione di selezione, invece, l'istruction sarà applicata sulle righe non catturate dal adress utilizzato.
L'inversione può essere utilizzata con qualsiasi tipo di adress.
SED da la possibilità di selezionare un intervallo di righe di testo su cui eseguire una o più istructions specificate: per mezzo di due adress separati da virgole è possibile definire tale intervallo.
La prima riga dell'intervallo è quella selezionata da adress1, l'ultima riga dell'intervallo è quella che sarà elezionata da adress2; su tutte le righe esistenti fra la prima e l'ultima, comprese la prima e l'ultima, sarà eseguita l'istruction dello script.
Se la riga caricata nel pattern space è in effetti all'interno dell'intervallo definito con i due adress, allora su tale riga è eseguita l'istruction.
L'adress che identifica la prima riga dell'intervallo può essere di tipo diverso dall'adress che identifica l'ultima riga dell'intervallo; per cui, ad esempio, il primo adress può ssere di tipo numero di linea, mentre il secondo può essere di tipo espressione regolare.
L'inversione della selezione, definita dal modificatore !, è applicabile anche agli intervalli.
In pratica le istructions dello script saranno applicate su tutte le righe che non fano parte dell'intervallo o degli intervalli individuati con i due adress.
Merita maggiore attenzione un intervallo definito da due adress di tipo espressione regolare, in quanto la corrispondenza al modello, sia del primo che del secondo adress, può sussistere in più righe dello stream di input.
SED parte confrontando le righe con l'espressione del primo adress; nel momento in cui verifica la corrispondenza, tale riga viene selezionata e su di essa vengono eseguite le istructions dello script.
Le righe successive a quella corrispondente al primo adress vengono invece confrontate con il modello regexp del secondo adress; se la corrispondenza non viene verificata, esse sono comunque selezionate, in quanto membri dell'intervallo definito dai due adress di tipo regexp; su ciascuna di queste righe vengono applicate le istructions dello script.
Quando la corrispondenza con il modello del secondo adress è verificata, vuol dire che siamo arrivati all'ultima riga dell'intervallo; tale riga viene selezionata e su di essa vengono esguite le istructions dello script.
A questo punto, SED riparte a confrontare le righe successive all'ultima riga dell'intervallo, con il modello regexp del primo adress, e nel caso vi sia una corrispondenza, il ciclo descritto precedentemente si ripete.
Una delle esigenze che possono sorgere quando si utilizza SED è quella di processare con più istructions una riga che è stata selezionata con un adress.
La soluzione potrebbe essere quella di passare alla riga di comando, attraverso una serie di opzioni -e, più script che hanno in comune il medesimo adress.
Per eseguire due istructions sul medesimo intervallo di righe, adottando la soluzione sopra esposta, si ha:
Per facilitare le cose SED dà la possibilità di raggruppare più istructions sotto un medesimo adress.
Il raggruppamento di più istructions sotto un unico adress comporta che, dopo l'inserimento dell'adress, deve essere aperta la parentesi graffa; tale parentesi graffa deve essere l'ultimo carattere della riga.
Le istructions da raggruppare sotto l'andress vanno inserite, una per riga, a partire dalla riga successiva a qulla che contiene la parentesi graffa aperta.
Nella riga successiva all'ultima istructions da raggruppare viene inserita la parentesi graffa chiusa che termina lo script.
Da notare il mutamento della sintassi tipica della riga di comando: lo script che contiene il raggruppamento è l'ultimo argomento della riga di comando, mentre il file da processare è l'argomento che segue le altre opzioni del comando sed.
Questo mutamento di sintassi non è vincolante, ma è stato adottato per continuare ad usfruire della facilitazione di completamento automatico dei nomi dei file tipico di bash; se infatti si usasse la sintassi normale, per cui il nome del file da processare è l'ultimo argomento della linea di comando di SED, tale nome andrebbe sull'ultima riga dopo la chiusura della parentesi graffa (e dell'apice singolo); ho potuto notare che in tale posizione il completamento automatico non funaziona.
É il caso di ricordare che il raggruppamento di più istructions sotto un medesimo adress, implica che sulla stessa riga caricata nel pattern space siano applicate più istructions e quindi la seconda istructions agisce su una riga che può essere già stata modifcata dalla prima e così via.
L'adress di uno script serve a selezionare le righe su cui SED eseguirà una o più istructions.
Dal punto di vista logico si può affermare che grazie all'adress è estratto dallo stream di input un insieme di righe di testo; insieme sul quale è possibile operare una ulteriore selezione, estraendo un sottoinsime delle righe precedentemente selezionate; su tale sottoinsime è a sua volta possibile fare un altra selezione ed estrarre un ulteriore sottoinsieme.
Lo scopo degli script annidati è proprio quello di operare delle selezioni successive, partendo dall'insieme di righe che compongono l'intero file.
Gli adress descrivono, in sostanza, la proprietà caratteristica delle righe che faranno parte dell'insieme e dei successivi sottoinsiemi individuati.
La sintassi è molto simile a quella dela raggruppamento di istructions sotto un medesimo adress.
In questo modello di annidamento adress1, quello posto subito dopo l'opzione -e, effettua la prima selezione di un gruppo di righe; su questo insieme saranno eseguite le istruzioni o le ulteriore selezioni contenute all'interno della prima parentesi graffa aperta.
SED opera riga per riga, nel senso che applica tutti gli script sulla riga memorizzata in un dato momento nel pattern space e solo dopo carica nel pattern space la riga successiva.
Quindi, seguendo il modello, se la riga nel pattern space verifica la corrispondenza con adress1, su di essa sarà seguita per prima istruction1, che potrà modificare la riga; successivamente, su tale riga eventualmente modificata, sarà verificato adress2.Se la verifica di adress2 è positiva, su quella riga sarà eseguita prima istruction2.1 e poi istruction2.2.
A questo punto SED verifica se la riga eventualmente modificata dalle istructions eseguite precedentemente corrisponde ad adress3 e in caso positivo, opera una ulteriore e immediata verifica di corrispondenza con adress4.
Se la corrispondenza con adress4 è positiva, vengono eseguite istruction3.4.1 ed istruction3.4.2, dopo di che sul pattern space viene caricata la riga successiva ed il ciclo riparte da capo.
Questo meccanismo, anche se in modo un po particolare, consente comunque di selezionare e alterare un insieme di righe e successvamente di selezioanre ed alterare sottoinsiemi dell'insieme immediatamente precedente.
In paratica, sempre nel modello, le istructions di adress2 saranno eseguite solo se la riga corrisponde sia ad adress1 che ad adress2 e quindi, ragionando in termini insiemistici, se la riga ha le proprietà caratteristiche descritte sia nel primo che nel secondo adress.
Allo stesso modo le istructions di adress4 saranno eseguite se la riga corrisponde ad adress1, ad adress3 e ad adress4 e quindi, ragionando in termini insiemistici, se la riga ha le proprietà caratteristiche descritte nel primo, nel terzo e nel quarto adress (il quarto adress è annidato al terzo, il terzo è annidato al primo).
Una precisazione è necessaria sulla tipologia di adress da utilizzare nell'ambito degli script annidati.
Indubbiamente l'adress di tipo regexp è utilizzabile nel primo adress e nei successivi adress annidati al primo: le selezioni in tal caso saranno effettuate sulla base delle corrispondenze con i diversi modelli regexp
Discorso diverso va fatto per gli adress numero di riga; tale numero è infatti determinato contando le righe dello stream di input partendo dalla prima alla quale è assegnato l'ordinale 1; l'ordinale identifica la riga in modo assoluto rispetto alla posizione della stessa nello stream di input.
Utilizzare un adress di tipo numero di riga come primo adress di uno script che ne annida altri, non comporta problemi.
I problemi nascono rispetto agli adress successivi al primo; infatti la numerazione delle righe rimane sempre riferita alla posizione della riga rispetto allo stream di input; tale numerazione non viene ricalcolata in relazione alla posizione della riga nell'insieme precedentemente selezionato.
Le istructions p, l e = servono per inviare qualcosa allo standard output e quindi di provocare una stampa.
Con ciò non si vuol dire che queste sono le uniche istructions che comportano l'invio esplicito allo standard output, ma piuttosto che tale invio è la loro funzione principale o esclusiva.
L'istructions p invia allo standard output l'intera riga caricata nel pattern space.
Il pattern space ed il relativo ciclo di esecuzione non vengono in alcun modo alterati.
Il comportamento predefinito di SED è quello di inviare in ogni caso allo standard output la riga caricata nel pattern space.
L'utilizzo dell'istructions p, senza disabilitare il comportamento predefinito di SED attraverso l'opzione -n alla riga di comando, comporta che la riga sarà inviata allo standard output due volte: una prima volta a causa del comportamento predefinito di SED, una seconda volta a causa dell'esecuzione dell'istruction.
L'istructions l fa la stessa cosa di p con un unica importante differenza: tutti i caratteri non stampabili vengono sostituiti, in fase di output, con il loro relativo codice ottale secondo lo standard ASCII.
Se si utilizza GNU SED, i caratteri non stampabili saranno sostituiti, in fase di output, con i loro corrispondenti caratteri escape dello standard ANSI C; se il carattere escape non esiste sarà invece utilizzato lo standard ASCII in codice ottale.
L'istructions = invia allo standard output il numero della riga caricata sul pattern space; l'istruction non invia la riga caricata nel pattern space, ma solo il suo numero di riga calcolato in relazione allo stream di input da cui proviene.
Prima di vedere l'istruction per la sostituzione delle stringhe conviene definire alcuni concetti generali.
La sintassi generale dell'istruction di sostituzione è la segunete:
Il carattere s rappresenta il simbolo dell'istruction di sostituzione.
I caratteri / rappresentono i simboli di delimitazione delle varie parti dell'istructions.
Il pattern serve per individuare quale sia la stringa da sostituire (l'intera riga del pattern space o una qualsiasi sottostringa di essa).
Il replacement rappresenta la sequenza di caratteri che sostituisce la stringa individuata con pattern.
flag sono delle opzioni facoltative che definiscono particolari modalità di ricerca o di sostituzione delle stringhe, oppure particolari modalità di comportamento di SED quando la sostituzione è andata a buon fine.
La scelta del carattere / come delimitatore delle varie parti dell'istruction è convenzionale: il carattere di delimitazione può, quindi, essere cambiato.
Il carattere scelto come delimitatore è quello che compare immediatamente dopo al simbolo s; i delimitatori devono essere necessariamente tre:
Il pattern è un modello regexp; le regular expression consentono di individuare e selezionare delle sottostringhe da una stringa ricevuta come input.
La stringa di input è l'intera riga caricata sul pattern space.
Attraverso il linguaggio simbolico delle regular expression è possibile descrivere un modello con il quale sarà selezionata la sequenza di caratteri da sostituire.
La sequenza di caratteri trovata attraverso il modello
regexp può corrispondere all'intera riga memorizzata nel
pattern space, oppure solo ad una parte di essa, cioè ad una
sottostringa della stringa di input.
Nel primo caso la sostituzone comporterà la modifica
dell'intera riga nel pattern space, la quale sarà quindi
completamente diversa da quella esistente prima della
sostiuzione.
Nel secondo caso invece la sostituzone riguarderà solo la
sequenza di caratteri parziale corrispondente al modello e
quindi la riga nel pattern space, dopo le sostituzioni, avrà
delle parti modificate e delle parti non modificate.
Quando il modello regexp è progettato per selezionare solo sottostringhe della riga nel pattern space, l'invio allo standard output, dopo la sostituzione delle parti selezionate, coinvolge in ogni caso l'intera riga nel pattern space, comprese le parti non modificate.
Di questo comportamento bisognerà tener conto quando si progetta il pattern dell'istruction s, in quanto, se si ha la necessità di selezionare e sostituire l'intera riga nel pattern space, si dovranno utilizzare il metacarattere ^ e il metacarattere $ per ancorare la corrispondenza all'inizio e alla fine della riga nel pattern space.
Ovviamente se nessuna sottostringa con quelle caratteristiche esiste nel pattern space, nessuna sostituzione sarà effettuata e l'invio allo standard output riguarderà l'intero pattern space (salva la soppressione dell'aoutput automatico).
L'utilizzo dell'istruction s, con il relativo pattern regexp, può convivere con un adress di tipo regexp.
In tal caso, l'azione di ricerca, selezione e sostituzione è operata solo sulle righe del pattern space che, preliminarmente, realizzano una corripondenza con l'adress di tipo regexp dello script che contiene l'istruction s
Quello che è importante capire è la differente funzione dell'adress di tipo regexp rispetto alla regexp del pattern di una istructions di sostituzione.
La regexp di un adress serve per selezionare la riga su cui saranno applicati le istructions collegate al medesimo adress (che possono essere istructions di sostituzione, ma anche istructions di altro tipo).
La regexp di una istructions di sostituzione serve per individuare quale porzione della riga caricata sul pattern space sarà sostituita con la stringa di replacement.
La parte replacement dell'istruzione di sostituzione rappresenta la stringa con cui sostitutuire la sottostringa trovata con il pattern.
In generale i caratteri della stringa di raplacement corrispondono a se stessi, anche se SED mette a disposizione dei metacaratteri che hanno dei significati speciali.
Il metacarattere & corrisponde all'intera sottostringa trovata con il pattern di ricerca.
In pratica SED nella stringa di replacement, al posto del simbolo &, inserisce l'intera sottostringa trovata con il pattern regexp.
Tale metacarattere è utile per realizzare una sostituzione che comporta un inserimento di una stringa arbitraria prima o dopo la stringa trovata con il pattern.
Il metacarattere \N, dove N è una cifra intera, serve per ripetere nella stringa di replacement una porzione della stringa trovata grazie al pattern espressione regolare.
La cifra N indica quale porzione ripetere nella sostituzione.
L'ordine delle porzioni è determinato dall'utilizzo dei metacaratteri di raggruppamento nel pattern regexp di ricerca.
I metacaratteri di raggruppamento sono \( e \) e servono per racchiudere una parte del modello regexp utilizzato per la ricerca; la stringa corrispondente alla parte del modello regexp racchiusa dentro i metacaratteri di raggruppamento è una sottostringa dell'intera stringa trovata dall'intero modello regexp.
Il valore di N, quindi, è scelto in relazione alla posizione nel pattern del reggruppamento a cui si vuole far riferimento.
Con il metacarattere \1 si ripete, nella stringa sostituente del replacement, la sottostringa individuata e selezionata dal primo raggruppamento nel pattern; con il metacarattere \3 si ripete, nella stringa sostituente del replacement, la sottostringa individuata e selezionata dal terzo raggruppamento nel pattern e così via.
Ovviamente se si utilizza il metacarattere \3 nel replacement, nel pattern devono esistere almeno 3 raggruppamenti, cioè tre sequenze di caratteri racchiuse fra i metacaratteri \( e \).
Il metacarattere \L attiva la conversione automatica in minuscolo dei caratteri che formano la stringa di replacement; la conversione automatica riguarda solo i caratteri che si trovano dopo il simbolo \L e non quelli prima; la conversione automatica cessa quando nella stringa di replacement è inserito il metacarattere \E oppure il metacarattere \U.
Il metacarattere \U è speculare al metacarattere \L, soltanto che con esso viene attivata la conversione automatica in maiuscolo.
La conversione automatica, anche in tal caso, cessa quando nlla stringa di replacement viene incontrato il metacarattere \E, oppure il metacarattere \L.
Il metacarattere \E dovrebbe essere ormai chiaro, esso disattiva la conversione automatica, in minuscolo o in maiuscolo, in precedenza attivata con il metacarattere \L oppure \U.
Il metacarattere \l sta ad indicare che il carattere successivo, nella stringa di replacement, deve essere in ogni caso convertito in minuscolo; la conversione riguarda solo un carattere, cioè quello che immediatamente segue il metacarattere \l.
Il simbolo \u è speculare al simbolo \l, con l'unica differenza che il successivo carattere sarà convertito in maiuscolo.
Altra questione collegata al rplacement dell'istruction
s, attiene al modo
in cui si possono inserire caratteri di newline nella
stringa che sostitiuisce quella trovata con il pattern.
Anche in tal caso entra in gioco il simbolo \.
Gli script che seguono nei due successivi esempi sono alternativi ed hanno come scopo quello di inserire un newline dopo un carattere . che conclude una frase della riga caricata nel pattern space; si può dire che un . conclude una frase quando dopo di esso vi siano 0 o più caratteri di spaziatura e successivamente una lettera maiuscola qualsiasi (lo spazio e la lettera maiuscola dopo il punto, sono presi come indice del fatto che sulla medesima riga riprende una frase diversa, che noi invece vogliamo portare sulla riga successiva inserendo un newline).
Quest'ultimo modo di inserire il newline è funzionante per GNU SED, ma non è detto che sia funzionante per i programmi SED non GNU.
I flag sono tutti facoltativi e definiscono particolari modalità di ricerca o di sostituzione delle stringhe, oppure particolari modalità di comportamento di SED quando la sostituzione è andata a buon fine.
Per capire la funzione dei flag g ed N (N valore numerico) è necessario fare una premessa su come SED esegue la ricerca e la sostituzione sulla riga caricata nel pattern space.
Il modello regexp del pattern serve a ricercare una sottostringa della riga caricata nel pattern space; tale sottostringa viene sostituita con la stringa di replacement.
Non è infrequente che la sottostringa corrispondente al modello di ricerca esiste più volte sulla riga caricata nel pattern space.
Se si ha l'esigenza di sostituire tutte le sottostringhe corrispondenti al modello di ricerca è necessario utilizzare il flag g.
Se, invece, si vuole sostituire solo una specifca corrispondenza esistente sulla riga caricata nel pattern space, ad esempio solo la seconda o solo la terza, si potrà utilizzare un valore numerico N.
Il valore numerico N consente di specificare quale corrispondenza, se esiste, deve essere sostituita con la stringa di replacement.
I flag p e w definiscono un azione supplementare che SED dovrà eseguire nel caso in cui la sostituzione di stringa vada a buon fine.
Il flag p invia sullo standard output la riga caricata nel pattern space se ed in quanto le sostituzioni sono state effettuate.
Se l'invio automatico allo standard output
non è stato disabilitato, la riga caricata nel pattern
space viene in ogni caso stampata
, nel senso che
sarà mandata in output anche se su di essa non è stata
eseguita alcuna sostituzione; se invece le sostituzione
sono state eseguite, la riga nel pattern space viene
stampata
due volte.
Il flag w scrive su un file le righe caricate nel pattern space, se ed in quanto le sostituzioni sono state effettuate; se nessuna sostituzione è effettuata, perchè non c'è una sottostringa corrisponde all'adress dello script, oppure sulla riga non vi è una corrispondenza con il pattern dell'istruction s, quella riga non sarà scritta sul file.
Il path completo del file su cui scrivere le righe viene indicato dopo il simbolo w, separato da uno spazio; se il file esiste già esso viene sovrascritto, se non esiste viene creato ex novo.
Da questo esempio si può anche notare che i flag di una istruction di sostituzione possono essere più di uno ed in tal caso essi vanno indicati uno di seguito all'altro, senza separarli con spazi.
Il flag i rende la ricerca delle corrispondenze case insensitive.
Infatti, di default, lettere maiuscole e lettere minuscole sono da considerare come caratteri diversi; con il flag i, SED assume l'uguaglianza fra una lettera in minuscolo e la stessa lettera in maiuscolo.
É nececessario precisare che il flag i agisce solo sulle ricerche collegate al pattern dell'istruction s, e non anche sulle ricerche collegate agli adress di tipo regexp
Il flag e fa si che la riga nel pattern space, così come risultante dopo le sostituzioni di stringa, sia considerata da SED come un comando eseguibile dalla shell predefinita del sistema (normalmente Bash).
In pratica, eseguite le sostituzioni, SED invia la riga esistente nel pattern space alla shell Bash, che considera l'input ricevuto da SED come un comando esguibile.
Lo standard output di Bash è automaticamente rediretto a SED, cosicché i risultati dell'esecuzione del comando sono memorizzati nel pattern space al posto del suo contenuto originario.
Se l'input passato da SED a Bash non è un comando eseguibile, Bash reagirà con un messaggio di errore, che, normalmente, è inviato sullo standard error; lo standard error, non è rediretto su SED e quindi i messaggi di errore non saranno memorizzati nel pattern space.
É il caso di ricordare che, qualora dopo l'istructions di sostituzione con il flag e ci siano altre istructions da applicare sul medesimo pattern space, queste agiranno sulla sequenza di caratteri restituita da Bash come risultato dell'esecuzione del comando.
Il flag m agisce sul modo in cui i metacaratteri ^ e $ eventualmente contenuti nel pattern sono valutati, qualora l'istruction s agisca su un pattern space multiriga.
Per una spiegazione più dettagliata del funzionamento del flag m, si rimanda alla sezione che tratta dei pattern space multi riga (Ancora non completata).
L'istruction d cancella
la riga caricata nel pattern
space.
Se tale istruction non viene utilizzata insieme ad un adress,
SED cancella tutte le righe che di volta in volta sono caricate
nel pattern space.
Se l'adress è di tipo regexp e la corrispondenza è verificata rispetto ad una sottostringa della riga nel pattern sapce, la cancellazione riguarda sempre l'intera riga e non solo la parte che corrisponde all'espressione regolare dell'adress.
La cancellazione del pattern space ha alcune conseguenze importanti:
L'istructions i\ comporta l'inserimento di testo all'inizio.
L'istructions a\ comporta l'aggiunta di testo alla fine.
L'utilizzo dei termini inserimento di testo
all'inizio
e aggiunta del testo alla fine
può
essere fuorviante, ed è quindi necessario precisare quali
sono gli effetti di tali istructions.
Nessuna delle due istruction, infatti, modifica il pattern space, nel senso che l'istructions i\ non inserisce all'inzio del pattern space una ulteriore stringa di testo e l'istructions a\ non aggiunge alla fine del pattern space un ulteriore stringa di testo.
Le due istructions agiscono esclusivamente in fase di
output.
Questo dettaglio è di fondamentale importanza, perché le
istructions successive ad i\ oppure ad a\, da eseguire sulla medesima riga
nel pattern space, non saranno condizionate dal testo da esse
inserito
o aggiunto
.
La sintassi generale delle istructions è il segunete.
Le righe su cui eseguire le istructions possono essere
selezionate attraverso l'utilizzo di un address posto prima
del simbolo i\ o
a\ senza spazi
separatori.
Possono essere utilizzati adress di qualsiasi tipo.
Secondo lo standard POSIX non è ammessa l'esecuzione delle istructions i\ od a\ su un intervallo di righe.
Questa limitazione è superata dallo standard GNU.
In pratica il testo viene inserito o aggiunto, secondo le
regole che vedremo in seguito, per ogni riga compresa
nell'intervallo selezionato.
Il testo da inserire o aggiungere può stare su una o più righe; se sta su più righe, in corrispondenza di ogni backslash \, sarà inviato un newline in fase di output.
L'ultima riga da inserire o aggiungere non termina mai con un backslash. (se il testo da inserire o aggiungere sta solo su una riga, allora quell'unica riga non dovrà terminare con un backslash)
Altro aspetto della sintassi è che dopo il simbolo dell'istructions i od a vi deve essere un backslash ed il testo da inserire deve essere scritto nella riga succesiva.
GNU SED consente anche una sintassi semplificata quando il testo da inserire o aggiungere sta solo su una riga:
Come si può vedere lo standard GNU consente di indicare il testo da inserire o da aggiungere subito dopo il simbolo i od a, senza l'utilizzo del backslash e senza la necessità di scrivere il testo nella riga successiva.
La specificità di tali istructions, rispetto a quelle finora viste, deriva dal fatto che non viene alterato in alcun modo il pattern space corrente, in quanto l'esecuzione delle stesse agisce nella fase di invio all'output del testo esistente nel pattern space.
L'esecuzione dell'istruction i\, o dell'istruction a\, nell'ambito del ciclo di
esecuzione relativo alla riga caricata nel pattern space, non
comporta l'immediato invio in output del testo da
inserire
o aggiungere
: esso è rimandato ad un
momento successivo all'interno dello stesso ciclo di
esecuzione.
Con l'istruction i\,
l'invio allo standard output del testo da inserire
avviene immediatamente prima dell'invio allo standard output
della riga caricata nel pattern space.
L'invio allo standard output della riga caricata nel pattern space può avvenire per due diverse cause:
Se dopo l'istructions \i è eseguita una istruction per l'invio esplicito allo standard output della riga caricata nel pattern space, prima di tale invio sarà inviato il testo che segue l'istruction \i.
Se, invece, dopo l'esecuzione dell'istruction i\ non ci sono altri script che comportino l'invio esplicito allo standard output della riga nel pattern space, ma è attivo l'invio automatico alla fine del ciclo di esecuzione, prima di questo invio viene inviato il testo collegato all'istruction i\.
Se, in fine, è disattivato anche l'invio automatico, alla fine del ciclo di esecuzione, il testo collegato all'istruction \i viene comunque inviato allo standard output.
Con l'istructions a\,
l'invio allo standard output del testo da aggiungere
,
avviene dopo l'ultimo invio allo standard output della riga
caricata nel pattern space.
In pratica se è attivo l'invio automatico allo standard
output della riga nel pattern space, il testo da
aggiungere
viene inviato immediatamente dopo tale
invio automatico.
Se l'invio automatico è disattivato, ma esistono altri
script che implicano l'esecuzione di una istruction di invio
esplicito in output della riga nel pattern space, l'invio del
testo da aggiungere
avviene immediatamente dopo
l'esecuzione dell'ultima istruction di invio esplicto in
output del pattern space.
Se, infine, è disattivato l'invio automatico e non vi sono
script di invio esplicito della riga caricata nel pattern
space, il testo da aggiungere
viene in ogni caso
inviato allo standard output alla fine del ciclo di
esecuzione relativo a quella riga.
La sostituzione di una intera riga in fase di output, implica la cancellazione del testo caricato nel pattern space e l'invio allo standard output del testo in sostituzione che segue l'istruction c\.
La cancellazione del pattern space comporta il caricamento di una nuova riga dallo stream di input e l'inizio su di essa di un nuovo ciclo di esecuzione.
La sintassi generale dell'istruction è la seguente:
L'istruction c\ può essere utilizzata con qualsiasi tipo di adress.
Quando l'istruction c\ viene utilizzata con una coppia di adress che selezionano un intervallo di righe, tutte le righe dell'intervallo vengono cancellate, e dopo la cancellazione dell'ultima riga viene inviato allo standard output la riga o le righe di testo collegate all'istruction c\ medesima.
Fondamentale è ricordare che l'invio allo standard output non avviene dopo ogni cancellazione di riga, ma solo dopo la cancellazione dell'ultima riga dell'intervallo.
GNU SED consente anche una sintassi semplificata quando il testo che sostituisce sta solo su una riga:
Il testo che sostituisce è indicato subito dopo il simbolo c, senza l'utilizzo del backslash e senza la necessità di scrivere il testo nella riga successiva.
La traslazione carattere per carattere è semplicemente la sostituzione di un carattere con un altro carattere su tutta la riga caricata nel pattern space.
La sintassi generale dell'istruction è la seguente:Il simbolo Y è l'istruction di traslazione.
Gli slash hanno una funzione di delimitazione.
CHAR_ORIG è l'insieme di caratteri da traslare
CHAR_DEST è l'insieme di caratteri con cui traslare
l'istructions Y accetta qualsiasi tipo di adress per la selezione della riga su cui operare, compresa la selezione di un intervallo di righe.
Il numero di caratteri indicati in CHAR_ORIG deve essere uguale al numero di caratteri indicato in CHAR_DEST; la sostituzione del primo carattere di CHAR_ORIG avviene con il primo carattere di CHAR_DEST, il secondo carattere di CHAR_ORIG è sostituito con il secondo carattere di CHAR_DEST e così via.
L'insieme di caratteri di CHAR_ORIG e CHAR_DEST può essere indicato in forma di intervalli secondo l'ordine dello standard ASCII.
L'istruction n, nel momento in cui viene eseguita, svuota il pattern space e su di esso carica la riga immediatamente successiva dallo stream di input.
Se è attivo l'output automatico, il pattern space, prima di essere svuotato, viene inviato allo standard otuput.
L'aspetto fondamentale dell'istruction n è che non viene iniziato un nuovo ciclo di esecuzione, nel senso che SED continuerà ad applicare sulla nuova riga caricata nel pattern space gli script successivi all'istruction n, fino alla fine del ciclo attuale.
L'istruction n può essere utilizzata in combinazione con qualsiasi adress; ciò consente di condizionare il caricamento della riga successiva a determinate caratteristiche della riga corrente.
In questo modello, se la riga corrente nel pattern space
corrisponde al modello regexp pattern 1, viene eseguita l'istruction
n e la riga successiva è
caricata nel pattern space (l'output automatico è disattivato e
quindi nulla è inviato allo standard output).
Gli script successivi all'istruction n sono applicati sulla nuova riga.
Se la nuova riga corrisponde al modello pattern 2 il pattern space viene svuotato (istruction d), viene caricata la riga successiva ed inizia nuovo ciclo di esecuzione (in pratica la riga caricata dopo l'istruction d viene confrontata con pattern 1).
Se la riga caricata con l'istructions n non corrisponde a pattern 2, viene confrontata con pattern 3; se c'è corrispondenza vengono applicati tutti gli script annidati in pattern 3:
Se la riga caricata con l'istruction n non corrisponde nemmeno a pattern 3, nulla viene eseguito (l'output automatico è disattivato), il ciclo di esecuzione termina, viene caricata nel pattern space la riga successiva ed inizia un nuovo ciclo di esecuzione
.