[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]


Capitolo 318.   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 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.

Figura 318.1. Flussi di dati che interessano SED.

               Direttive di elaborazione
                            |
                            |
                            V
                       .---------.
    dati in ingresso   |         |     dati in uscita
---------------------->|  S E D  |----------------->
                       |         | 
                       `---------'

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

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

Alcune opzioni

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

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

Figura 318.2. Struttura semplificata del funzionamento di SED.

        .--------------> Lettura di una riga
        |                        |
        |                        |
        |                        |
        |                        |
        |                        |
azione predefinita               |
        ^                        V
        |            La riga letta appartiene a
        |            uno dei gruppi selezionati?
        |                |          |
        |             NO |          | SÌ
        |<---------------'          |
        |                           V
        |                 Esegue le elaborazioni
        |                 previste per questa riga
        |                           |
        |                           |
        `<--------------------------'

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.

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 318.1. 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...    Sequenze.
   x-y    x-y    Intervalli.
   [.   .]    Elementi di collazione.
   [=   =]    Caratteri equivalenti.
   [:   :]    [:   :]    Classi di caratteri.

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

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

318.4.1   Selezione delle righe

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.

318.4.2   Comandi comuni

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.

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 si continuazione ha un significato speciale in SED, pertanto non va usata se non si conosce esattamente il risultato che si ottiene effettivamente.

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

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.

Selezione delle righe

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

Sostituzione del contenuto delle righe

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.

Raggruppamenti
#!/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.

318.6   Riferimenti

Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- 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]