[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]
SED è un programma in grado di eseguire delle trasformazioni elementari in un flusso di dati di ingresso, proveniente indifferentemente da un file o da una pipeline. Questo flusso di dati viene letto sequenzialmente e la sua trasformazione viene restituita attraverso lo standard output.
Il nome è l'abbreviazione di Stream 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.
|
In linea di principio, SED non consente di indicare dei caratteri speciali nei suoi comandi attraverso delle sequenze di escape. |
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.
-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.
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 318.2 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.
|
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
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.
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 318.1. Riepilogo delle espressioni regolari di SED (BRE).
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 direttamente 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.(1)
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.
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.
n
Un numero puro e semplice, indica precisamente la riga n-esima.
$
Un dollaro rappresenta l'ultima riga dell'ultimo file.
/espressione_regolare_elementare/
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 (\/).
\xespressione_regolare_elementarex
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 che 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.
#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).
s/espressione_regolare_elementare/rimpiazzo/[parametri]
sxespressione_regolare_elementarexrimpiazzox[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 seguente:
g
esegue l'operazione di rimpiazzo per tutte le corrispondenze che si possono avere sulla stessa riga, senza limitarsi alla prima soltanto;
p
se la sostituzione ha avuto luogo, emette la riga risultante (il pattern space);
n
rimpiazza solo nell'ambito dell'n-esima corrispondenza con l'espressione regolare;
w file
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.
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.
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.
$
sed "" prova.txt
Legge il file prova.txt
e lo riemette tale e quale, dal momento che non è stato specificata alcuna direttiva per il programma di elaborazione.
$
sed -n 'p' prova.txt
Si ottiene lo stesso risultato dell'esempio precedente, perché prima viene usata l'opzione -n con cui si inibisce la riemissione predefinita delle righe lette, ma poi si specifica una direttiva contenente il comando p applicato a tutte le righe del flusso in ingresso.
$
sed -n '1,10/p' prova.txt
Emette solo le prime 10 righe del file.
$
sed '/.\{81,\}/d' prova.txt
Elimina le righe più lunghe di 80 caratteri.
$
sed '/^$/d' prova.txt
Elimina tutte le righe vuote.
$
sed '/^---INIZIO---$/,/^---FINE---$/d' prova.txt
Elimina tutte le righe comprese negli intervalli delimitati da righe contenenti esclusivamente la stringa ---INIZIO--- e ---FINE---.
$
sed -n '/^---INIZIO---$/,/^---FINE---$/p' prova.txt
Emette tutte le righe comprese negli intervalli delimitati da righe contenenti esclusivamente la stringa ---INIZIO--- e ---FINE---.
$
sed 's/andato/venuto/' prova.txt
Sostituisce in ogni riga la prima occorrenza della stringa «andato» con la stringa «venuto».
$
sed 's/andato/venuto/g' prova.txt
Sostituisce tutte le occorrenze della stringa «andato» con la stringa «venuto».
$
sed 's/^/ /' prova.txt
Aggiunge quattro spazi all'inizio di ogni riga del file.
$
sed 's/\(.*\):\(.*\):\(.*\):\(.*\):\(.*\):\(.*\):\(.*\)/\1:\3/' /etc/passwd
Seleziona solo il primo e il terzo campo del file /etc/passwd
; in pratica, preleva il nominativo e il numero UID.
#!/bin/sed -nf { p w registro }
L'esempio mostra l'unione di due comandi riferiti allo stesso gruppo di righe (tutte). Lo scopo è quello di emettere le righe attraverso lo standard output e di annotarle anche in un file denominato registro
.
Si osservi il fatto che la parentesi graffa di chiusura deve essere indicata da sola (come si vede nell'esempio) e di conseguenza può essere opportuno fare altrettanto per quella di apertura. |
$
sed -n -e 'p' -e 'w registro' prova.txt
Questo esempio fa la stessa cosa di quello precedente, con la differenza che i comandi sono stati separati in due direttive riferite allo stesso gruppo di righe, inoltre si elaborano le righe del file prova.txt
.
Sed tutorials
daniele @ swlibero.org
1) È bene osservare che in uno script del genere non è possibile fare riferimento alle variabili di ambiente.
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome sed_introduzione.html
[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]