Questo documento sfrutta i fogli di stile (CSS); senza il supporto dei fogli di stile, benché il testo sia comunque visualizzabile, non saranno visibili ne le formattazioni ne la struttura della pagina.

Sommario    Precedente    Successivo

Guida sistematica a SED - parte 01

L'istruction per la sostituzione di stringa

Contenuti della Sezione

  1. L'istruction per la sostituzione di stringa
    1. Concetti generali
    2. L'istruction s/pattern/replacement/flag: sintassi generale
    3. L'istruction s/pattern/replacement/flag: i delimitatori
    4. L'istruction s/pattern/replacement/flag: il pattern
      1. Il pattern di ricerca e l'adress di tipo regexp: relazioni
    5. L'istruction s/pattern/replacement/flag: il replacement
      1. Il metacarattere &
      2. Il metacarattere di escape \
      3. Il metacarattere \N (N è un valore numerico)
      4. I metacaratteri \l - \L - \u - \U - \E (GNU SED)
      5. Inserire caratteri di newline nel replacement
    6. L'istruction s/pattern/replacement/flag: i flag
      1. I flag g e il flag N (N valore numerico)
      2. Il flag p e il flag w
      3. Il flag i
      4. Il flag e (GNU SED)
      5. Il flag m (GNU SED)

Concetti generali

Prima di vedere l'istruction per la sostituzione delle stringhe conviene definire alcuni concetti generali.

L'istruction s/pattern/replacement/flag: sintassi generale

La sintassi generale dell'istruction di sostituzione è la segunete:

Sintassi generale dell'istruction di sostituzione
s/pattern/replacement/flag

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.

L'istruction s/pattern/replacement/flag: i delimitatori

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:

  1. quello subito dopo il simbolo s
  2. quello che conclude il pattern
  3. quello che conclude il replacement
Esempio: Usare il simbolo % come delimitatore
s%pattern%replacement%flag

L'istruction s/pattern/replacement/flag: il pattern

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.

Esempio: Selezionare e sostituire l'intera riga nel pattern space
s/^.\{1,\}$/raplacement/
Esempio: Selezionare e sostituire una sottostringa della riga nel pattern space
s/"[^"]\{1,\}"/replacement/

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).

Il pattern di ricerca e l'adress di tipo regexp: relazioni

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

Esempio: Adress espressione regolare e istruction di sostituzione
/^#/s/"[^"]\{1,\}"/rplacement/

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.

L'istruction s/pattern/replacement/flag: il replacement

La parte replacement dell'istruzione di sostituzione rappresenta la stringa con cui sostitutuire la sottostringa trovata con il pattern.

Esempio: Una semplice sostituzione
sed -e 's/ UNIX /Unix system/' miofile.txt

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 &

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.

Esempio: Aggiungere una stringa dopo la stringa selezionata con il pattern
sed -e 's/ [Uu]nix /&system/' miofile.txt

Il metacarattere di escape \

Il metacarattere di escape \ serve per due scopi fondamentali:
  • il primo è quello di togliere il significato speciale agli altri metacaratteri, per cui, se sono precduti dall'escape, essi corrisponderanno solo a se stessi;
  • il secondo è quello di consentire l'utilizzo, all'interno del pattern e della stringa replacement, dei caratteri che sono stati utilizzati come delimitatori.
Esempio: Togliere il significato speciale agli altri metacaratteri
sed -e 's/Mengucci e C/Mengucci \& C/' miofile.txt
Esempio: Utilizzare il carattere di delimitazione all'interno del pattern o del replacement
sed -e 's/\/tizio\//\/caio\//' miofile.txt

Il metacarattere \N (N è un valore numerico)

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.

Esempio: Selezionare e ripetere una porzione di stringa
sed -e 's/"\([^"]*\)"/@\1@/' miofile.txt
Esempio: Selezionare e ripetere due porzioni di stringa
sed -e 's/\(on\) *\(off\)/\1-\2/' miofile.txt

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 \).

I metacaratteri \l - \L - \u - \U - \E (GNU SED)

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.

Esempio: Conversione automatica in minuscolo di parti della stringa sostituente
sed -e 's/"\([^"]*\)"/@\L\1\E@/' miofile.txt

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.

Esempio: Conversione automatica in minuscolo di un carattere della stringa sostituente
sed -e 's/"\([^"]*\)"/@\l\1@/' miofile.txt

Il simbolo \u è speculare al simbolo \l, con l'unica differenza che il successivo carattere sarà convertito in maiuscolo.

Inserire caratteri di newline nel replacement

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).

Esempio: Inserire un newline con SED non GNU
sed -e 's/\([^.]\{1,\}\)\. *\([A-Z]\)/\1.\
\2/g'
Esempio: Inserire un newline con SED GNU
sed -e 's/\([^.]\{1,\}\)\. *\([A-Z]\)/\1.\n\2/g'

Quest'ultimo modo di inserire il newline è funzionante per GNU SED, ma non è detto che sia funzionante per i programmi SED non GNU.

L'istruction s/pattern/replacement/flag: i flag

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.

I flag g e il flag N (N valore numerico)

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.

Esempio: Sostituire solo la prima corrispondenza al pattern
sed -e 's/"\([^"]*\)"/@\1@/' miofile.txt

Se si ha l'esigenza di sostituire tutte le sottostringhe corrispondenti al modello di ricerca è necessario utilizzare il flag g.

Esempio: Sostituire tutte le corrispondenze al pattern
sed -e 's/"\([^"]*\)"/@\l\1@/g' miofile.txt

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.

Esempio: Sostituire solo l'ennesima corrispondenza al pattern
sed -e 's/"\([^"]*\)"/@\l\1@/3' miofile.txt

Il flag p e il flag w

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.

Esempio: Scrivere il pattern space su un file
sed -e 's/"\([^"]*\)"/@\l\1@/gw ../new.txt' old.txt

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

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 (GNU SED)

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 (GNU SED) - Rinvio

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).