[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 667.   SED: introduzione

SED è un programma in grado di eseguire delle trasformazioni elementari in un flusso di dati di ingresso, proveniente indifferentemente da un file o da un condotto. Questo flusso di dati viene letto sequenzialmente e la sua trasformazione viene restituita attraverso lo standard output.

Il nome è l'abbreviazione di Stream oriented editor, che descrive istantaneamente il senso di questo programma: editor di flusso. Volendo usare altri termini, lo si potrebbe definire come un programma per la modifica sequenziale di un flusso di dati espressi in forma testuale.

Volendo vedere SED come una scatola nera, lo si può immaginare come un oggetto che ha due ingressi: un flusso di dati in ingresso, composto da uno o più file di testo concatenati assieme; un flusso di istruzioni in ingresso, che compone il programma dell'elaborazione da apportare ai dati; un flusso di dati in uscita che rappresenta il risultato dell'elaborazione.

Figura 667.1. Flussi di dati che interessano SED.

sed

In linea di principio, SED non consente di indicare dei caratteri speciali nei suoi comandi attraverso delle sequenze di escape.

Nei sistemi GNU è disponibile normalmente GNU SED. (1)

667.1   Avvio dell'eseguibile

SED è costituito in pratica dall'eseguibile sed, il quale interpreta un programma scritto in un linguaggio apposito, che gli viene fornito come argomento della riga di comando, o in un file.

sed [opzioni] [programma_di_elaborazione] [file...]

Il testo del programma, o il nome del file che lo contiene, può essere indicato attraverso delle opzioni adatte, oppure, in loro mancanza, può essere indicato come primo degli argomenti che seguono le opzioni. Alla fine possono essere indicati i file da elaborare e in loro mancanza si usa lo standard input.

Opzione Descrizione
-e istruzioni
--expression=istruzioni
Questa opzione, che può essere utilizzata anche più volte, permette di specificare delle istruzioni SED che si aggiungono alle altre eventualmente già indicate.
-f file_delle_istruzioni
--file file_delle_istruzioni
Questa opzione permette di indicare un file contenente una serie di istruzioni SED. Anche questa opzione può essere usata più volte, aggiungendo ogni volta altre istruzioni al programma globale.
-n
--quiet
--silent
In condizioni normali, alla fine di ogni ciclo, SED emette il contenuto di quello che viene definito come pattern space. In pratica, ogni riga letta ed elaborata viene emessa attraverso lo standard output senza bisogno di un comando apposito. Utilizzando questa opzione, si fa in modo di evitare tale comportamento, così che il programma di elaborazione interpretato da SED deve ordinare quando emettere ogni riga.

667.2   Logica di funzionamento

Il primo compito di SED, una volta avviato, è quello di raccogliere tutto ciò che deve andare a comporre il programma di elaborazione: può trattarsi di direttive fornite singolarmente attraverso l'opzione -e e di gruppi di direttive fornite all'interno di file appositi, indicati attraverso l'opzione -f. In particolare, SED si prende cura di mantenerne intatto l'ordine. Successivamente, concatena i dati in ingresso secondo la sequenza indicata dei file posti alla fine della riga di comando, oppure utilizza direttamente lo standard input.

Lo schema che appare nella figura 667.3 si avvicina all'idea del funzionamento di SED: il flusso in ingresso viene letto sequenzialmente, una riga alla volta; ogni volta la riga viene messa in un'area transitoria, nota come pattern space; viene confrontata la riga con ogni direttiva del programma di elaborazione e se nessuna di queste direttive coincide, la riga non viene elaborata, compiendo semplicemente l'azione predefinita prima di passare al prossimo ciclo di lettura. Se una o più direttive del programma di elaborazione corrispondono alla riga, vengono eseguite sequenzialmente le elaborazioni previste; poi, alla fine, si passa comunque per l'esecuzione dell'azione predefinita.

Figura 667.3. Struttura semplificata del funzionamento di SED.

sed

L'azione predefinita di SED è l'emissione del contenuto dell'area transitoria, per cui, se non venisse fornita alcuna direttiva a SED, si otterrebbe almeno la riemissione completa dello stesso file ricevuto in ingresso:

sed "" pippo.txt[Invio]

L'esempio mostra proprio l'avvio dell'eseguibile sed allo scopo di interpretare una direttiva nulla, fornendo il file pippo.txt in ingresso. Il risultato è la riemissione del contenuto di questo file attraverso lo standard output.

Per impedire che questa azione si compia automaticamente, si utilizza l'opzione -n (ovvero --quiet o --silent). In questo modo, è compito delle direttive del programma di elaborazione il richiedere espressamente l'emissione della riga elaborata.

SED dispone di due aree transitorie per le elaborazioni: una che contiene la riga letta, che è già stata indicata; l'altra, definita come hold space, viene gestita eventualmente attraverso le direttive del programma di elaborazione interpretato da SED. L'utilizzo di questa seconda area di memoria non viene mostrato in questo capitolo.

Dal momento che SED è un programma storico dei sistemi Unix, è bene tenere presente le limitazioni che potrebbe avere in questo o quel sistema. In particolare, qualche realizzazione di SED potrebbe porre un limite alla dimensione delle righe. Questo fatto va tenuto presente quando si vogliono realizzare dei programmi «portabili», ovvero, da usare su piattaforme diverse, con sistemi operativi diversi.

Tabella 667.4. Riepilogo delle espressioni regolari di SED (BRE).

POSIX GNU Descrizione
.
.
Un carattere qualsiasi.
\
\
Escape.
^
^
Inizio riga.
$
$
Fine riga.
\|
Alternativa.
\(   \)
Raggruppamento.
\n
\n
Riferimento.
x*
x*
Zero o più caratteri qualsiasi.
x\?
Zero o al massimo un carattere qualsiasi.
x\+
Uno o più caratteri qualsiasi
x\{n\}
x\{n\}
Esattamente n volte x.
x\{n,\}
x\{n,\}
Almeno n volte x.
x\{n,m\}
x\{n,m\}
Da n a m volte x.
x\{,m\}
x\{,m\}
Da zero a m volte x.
[   ]
[   ]
Elenco.
[...xy...]
[...xy...]
Elenco contenente una sequenza.
[...x-y...]
[...x-y...]
Elenco contenente un intervallo.
[...[.   .]...]
Elenco contenente un Elemento di collazione.
[...[=   =]...]
Elenco contenente caratteri equivalenti.
[...[:   :]...]
[...[:   :]...]
Elenco contenente una classe di caratteri.

667.3   Script e direttive multiple

Di solito, si vede utilizzare SED con direttive fornite direttamente attraverso la stessa riga di comando. Volendo realizzare un programmino un po' più complesso, si potrebbe scrivere uno script che deve essere interpretato direttamente da SED. Per farlo, occorre iniziare il file in questione con una delle due intestazioni seguenti:

#!/bin/sed -f
#!/bin/sed -nf

Nel primo caso, si fa in modo di fornire all'eseguibile sed (si suppone che si trovi nella directory /bin/) l'opzione -f, in modo che il file stesso venga inteso correttamente come un programma di elaborazione; nel secondo, oltre a questo, viene aggiunta l'opzione -n, con la quale si inibisce l'emissione predefinita delle righe dopo ogni ciclo di elaborazione.

È utile osservare che in uno script del genere non è possibile fare riferimento alle variabili di ambiente.

Per quanto riguarda le direttive contenute nei file, queste utilizzano una riga per ognuna, dove le righe bianche o vuote vengono ignorate, assieme ai commenti che iniziano con il simbolo #:

direttiva_di_elaborazione
direttiva_di_elaborazione
...

Le direttive fornite attraverso la riga di comando sono solitamente istruzioni singole; per cui, volendo aggiungerne delle altre, si utilizzano più opzioni -e:

sed -e direttiva_di_elaborazione [-e direttiva_di_elaborazione]... file_in_ingresso...

Tuttavia, di solito è possibile indicare più direttive con una sola opzione -e, separandole con un punto e virgola:

sed -e direttiva_di_elaborazione[;direttiva_di_elaborazione]... file_in_ingresso...

L'uso di più direttive nella riga di comando, con o senza il punto e virgola, è sconsigliabile in generale, dal momento che dovendo scrivere un programma di elaborazione complesso è preferibile usare un file, trasformandolo eventualmente in uno script come è stato mostrato all'inizio di questa sezione.

667.4   Direttive

Ogni direttiva di un programma di elaborazione SED fa riferimento, esplicitamente o implicitamente, a un gruppo di righe, identificate in qualche modo, a cui vengono applicati dei comandi.

[selezione_righe]comando

Il modello sintattico mostra l'indicazione di un comando dopo la selezione delle righe; questo comando può essere un raggruppamento di comandi, indicato all'interno di parentesi graffe.

La selezione delle righe per una direttiva SED è il primo elemento importante per queste. La mancanza dell'indicazione di questa selezione rappresenta implicitamente la selezione di tutte le righe.

È importante osservare che le righe possono essere indicate anche attraverso la corrispondenza con un'espressione regolare, che comunque non deve essere confusa con i comandi che a loro volta possono avere a che fare con altre espressioni regolari.

Inoltre, è necessario ricordare che SED numera le righe a partire dalla prima del primo file, continuando fino alla fine dell'ultimo file, senza interrompere la numerazione.

Tabella 667.7. Selezione delle righe.

Direttiva Descrizione
n
Un numero puro e semplice, indica precisamente la riga n-esima.
$
Un dollaro rappresenta l'ultima riga dell'ultimo file.
/bre/
Un'espressione regolare elementare (BRE), racchiusa tra due barre oblique normali, serve a selezionare tutte le righe per cui corrisponde questo modello. Dal momento che la barra obliqua viene usata come delimitatore, se questa deve essere inserita nel modello, occorre proteggerla con una barra obliqua inversa (\/).
\xbrex
Si tratta sempre della selezione delle righe in base alla corrispondenza con un'espressione regolare, con la differenza che questa viene delimitata con un carattere differente, x, scelto liberamente, in modo da non interferire con i simboli usati nel modello. Se il modello dell'espressione regolare dovesse contenere anche questo carattere usato per la delimitazione, potrebbe essere protetto con l'aggiunta della barra obliqua inversa all'inizio (\x).
riga_iniziale,riga_finale
È possibile indicare un intervallo di righe, unendo assieme due riferimenti a righe, sia in forma numerica, sia attraverso le espressioni regolari. Per quanto riguarda l'individuazione della prima riga dell'intervallo, la cosa è abbastanza semplice; in particolare, se si tratta di un'espressione regolare, la prima corrispondenza indica la prima riga. Più complicato è il modo in cui viene preso in considerazione il secondo modello: se si tratta di un numero, questo rappresenta l'n-esima riga da raggiungere, che deve essere considerata inclusa nell'intervallo, ma se questo numero indica una riga precedente alla riga iniziale dell'intervallo, allora viene selezionata solo quella iniziale; se si tratta di un'espressione regolare, allora questo modello viene confrontato a partire dalla riga successiva a quella iniziale e alla corrispondenza raggiunta, si ottiene la riga finale dell'intervallo; se si tratta di un'espressione regolare, il confronto avviene a partire dalla riga successiva alla prima che è stata trovata.
riga_iniziale,riga_finale!
Se alla fine della selezione delle righe appare un punto esclamativo, questo rappresenta l'inversione della selezione, ovvero tutte le altre righe.

Come accennato, ogni direttiva si compone di una selezione di righe, in modo esplicito o implicito, e di un comando, ovvero di un raggruppamento di comandi racchiuso tra parentesi graffe. Vengono elencati di seguito i comandi più comuni.

Tabella 667.8. Comandi comuni.

Direttiva Descrizione
#commento
Il simbolo # rappresenta un comando speciale di SED che serve solo a fargli ignorare il testo che segue fino alla fine della riga (fino alla fine della direttiva). Trattandosi di un «comando», si applica a delle righe, che però non possono essere indicate.
Di solito, i commenti di questo tipo si inseriscono solo nei file contenenti direttive di un programma di elaborazione SED (eventualmente uno script eseguibile, realizzato nella forma che è già stata mostrata).
Se i primi due caratteri di un file del genere corrispondono alla stringa #n, SED funziona come se fosse stata usata l'opzione -n, per cui occorre fare attenzione ai commenti che appaiono nella prima riga di tali file.
s/bre/rimpiazzo/[parametri]
sxbrexrimpiazzox[parametri]
Con questo comando si vuole sostituire ciò che viene delimitato dall'espressione regolare con il testo di rimpiazzo, tenendo conto dei parametri posti eventualmente alla fine. L'espressione regolare e il testo di rimpiazzo sono delimitati e separati attraverso una barra obliqua normale, oppure da un altro simbolo scelto liberamente. Per inserire questa barra obliqua, o qualunque altro simbolo che svolga tale compito nell'espressione regolare, occorre proteggerlo con la barra obliqua inversa (\/, ovvero \x).
L'espressione regolare può essere realizzata in modo da individuare alcune parti, delimitate attraverso \( e \) (bisogna ricordare che si tratta di espressioni regolari elementari, ovvero di BRE); in tal caso, nella stringa di rimpiazzo si può fare riferimento a questi blocchi attraverso la forma \n, dove n è un numero da uno a nove, che indica l'n-esimo riferimento a questi raggruppamenti della parte di riga presa in considerazione dall'espressione regolare. Nella stringa di rimpiazzo si può anche utilizzare la e-commerciale (&) per fare riferimento a tutto il blocco di testo a cui corrisponde l'espressione regolare stessa.
I parametri in coda al modello, hanno il significato che viene descritto nei modelli successivi.
s/bre/rimpiazzo/g[altri_parametri]
sxbrexrimpiazzoxg[altri_parametri]
Con il parametro g si esegue l'operazione di rimpiazzo per tutte le corrispondenze che si possono avere sulla stessa riga, senza limitarsi alla prima soltanto.
s/bre/rimpiazzo/p[altri_parametri]
sxbrexrimpiazzoxp[altri_parametri]
Con il parametro p, se la sostituzione ha avuto luogo, emette la riga risultante (il pattern space).
s/bre/rimpiazzo/n[altri_parametri]
sxbrexrimpiazzoxn[altri_parametri]
Indicando un numero come parametro, si rimpiazza solo nell'ambito dell'n-esima corrispondenza con l'espressione regolare.
s/bre/rimpiazzo/w file \
  \[altri_parametri]
sxbrexrimpiazzoxw file \
  \[altri_parametri]
Con il parametro w, se la sostituzione ha avuto luogo, scrive la riga risultante nel file indicato.
q
Termina il funzionamento di SED senza altre elaborazioni e senza leggere altro dai file in ingresso.
d
Cancella l'area di memoria dove è stata accumulata la riga letta, avviando immediatamente un ciclo nuovo.
p
Emette la riga letta, con le modifiche eventuali che gli fossero state apportate nel frattempo. È importante ricordare che questo è il comportamento predefinito di SED, a meno che venga utilizzata l'opzione -n.
Nella preparazione di script per SED occorre tenere presente che alcune realizzazioni di questo emettono la riga una sola volta, anche se viene usato il comando p e non è stata usata l'opzione -n, mentre altre, come nel caso di GNU, lo fanno due volte. Questi due comportamenti opposti sono ammissibili secondo lo standard POSIX.
n
Questo comando permette di passare alla prossima riga, immediatamente, tenendo conto che se non è stata usata l'opzione -n, prima di passare alla prossima viene emessa quella precedente (come al solito). Lo scopo di questo comando è fare in modo che le direttive successive si trovino di fronte una riga nuova.
w file
Copia le righe nel file indicato, creandolo per l'occasione.
{ comandi }
Un raggruppamento di comandi può essere realizzato delimitandolo tra parentesi graffe. Tuttavia, è importante osservare che in questo caso, i comandi vanno indicati ognuno in una riga differente, inoltre la parentesi graffa di chiusura deve apparire da sola in una riga. Di solito, non c'è la necessità di usare un raggruppamento, dal momento che basta ripetere la stessa selezione di righe con un altro comando.

Alcuni comandi che qui non vengono descritti, richiedono una scomposizione in più righe, indicando la continuazione attraverso il simbolo \. Dal momento che questi comandi non vengono mostrati, quello che si vuole far notare è che la barra obliqua inversa come simbolo di continuazione ha un significato speciale in SED, pertanto non va usata se non si conosce esattamente il risultato che si ottiene effettivamente.

667.5   Esempi

In questa sezione vengono mostrati alcuni esempi dell'utilizzo di SED. A seconda dei casi e dell'utilità della cosa, si fa riferimento a direttive fornite nella riga di comando (con o senza l'opzione -e), oppure a uno script vero e proprio.

Elaborazioni banali
Selezione delle righe
Sostituzione del contenuto delle righe
Raggruppamenti

667.6   Riferimenti


1) GNU SED   GNU GPL


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome sed_introduzione.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory