Comando SED in Linux
Gli utenti di Linux e delle sue numerose distribuzioni lavorano a livello di riga di comando, chi occasionalmente e chi regolarmente, poiché alcuni processi possono essere eseguiti più velocemente o in maniera più efficiente tramite il terminale piuttosto che tramite l’interfaccia grafica. Tuttavia, a tale scopo, bisogna conoscere i vari comandi e il loro funzionamento. Uno di questi comandi in Linux è 'sed'.
Stream Editor (sed) si distingue da un consueto editor di testo. In Linux, SED è un comando che può essere utilizzato per leggere e adattare i flussi di dati, pertanto lo strumento è usato principalmente nella programmazione della shell. Ma come funziona?
Per cosa è utilizzato SED in Linux?
Il comando “sed” fa parte della dotazione di base di ogni installazione di Linux, poiché appartiene alle GNU Core Utilities (coreutils). Si tratta di un editor di testo non interattivo che non apporta modifiche dirette al file che si sta modificando ma che permette di creare prima un file temporaneo il cui contenuto viene poi trasferito al file di origine. SED procede riga per riga: ogni riga del file viene letta individualmente, elaborata e poi riprodotta. La funzione più importante di SED è quella di cercare determinate stringhe di caratteri nel file e poi sostituirle con altri caratteri.
In questo modo, usando un solo comando è possibile cambiare in maniera sostanziale un intero file quasi automaticamente. Integrando tali comandi in uno shell scripting, infatti, si semplificano notevolmente tutti i processi ridondanti. Per esempio, in questo modo è possibile curare i database o un codice sorgente esteso, poiché invece di modificare ogni voce a mano, con SED si può lavorare sull’intero file in una sola volta.
Sintassi e funzione del comando SED
Il comando SED lavora utilizzando eseguibili e si applica ai file. La funzionalità dei comandi (anche dello stesso SED) può essere estesa tramite cosiddette “opzioni”.
sed [opzione(i)] 'comando(i)' [file]
Potete inserire le opzioni direttamente all’interno del comando oppure eseguirli da un file. In tal caso, dovrete indicare il percorso del file al posto del comando.
Opzioni
Come di consueto per i comandi Linux, anche SED offre la possibilità di fissare parametri. Questi ultimi sono particolarmente importanti per il comando SED, poiché solo tramite di essi si rende chiaro come debba essere interpretato il comando indicato. Si tratta delle seguenti opzioni:
Opzione | Spiegazione |
-e | Quando è utilizzato uno o più script SED. |
-f | Quando lo script è stato estratto da un file. |
-n | I risultati non sono presentati. |
-i | Crea un file temporaneo che sostituisce il file di origine. |
-u | Non viene inserito un buffer di dati. |
-s | Più file vengono elaborati singolarmente invece che in un unico flusso di dati. |
-r | Il comando accetta termini regolari estesi. |
Le opzioni -e e -f sono le più importanti. Indicano se il comando è interno (e in tal caso si tratta di uno script SED) o se il comando debba fare riferimento a un file aggiuntivo. Spesso si può fare a meno dell’opzione -e, poiché è il caso standard. Tuttavia, se includete più di un comando allo stesso tempo, l’opzione deve essere attivata.
Se usate l’opzione -e, il parametro deve essere scritto direttamente prima del primo comando. Se usate altre opzioni, scrivetele prima del primo comando. Se includete altri comandi nel comando, inserite l’opzione anche davanti a essi.
L'opzione -n è molto importante, e probabilmente indispensabile per il vostro lavoro. Se il parametro non è impostato, ogni singola riga del file di testo letto sarà visualizzata sul terminale, il che non è molto utile, specialmente con grandi database. Se invece si attiva l’opzione, verranno visualizzate solo le righe interessate dal comando.
Comandi
Con un comando dite al comando cosa fare con il file sorgente tenendo conto delle opzioni specificate.
Comando | Spiegazione |
a | append: aggiunge una o più righe alle righe selezionate. |
c | change: sostituisce le righe selezionate con un nuovo contenuto. |
d | delete: elimina le righe selezionate. |
g | get: copia il contenuto da hold space in pattern space. |
G | GetNewline: aggiunge il contenuto hold space a pattern space. |
h | hold: copia il contenuto di pattern space in hold space. |
H | HoldNewLine: aggiunge il contenuto di pattern space a hold space. |
i | insert: aggiunge una o più righe prima della riga selezionata. |
l | listing: mostra tutti i caratteri non stampabili. |
n | next: passa al comando successivo per la riga successiva. |
p | print: mostra le righe selezionate. |
q | quit: termina il comando SED. |
r | read: legge le righe selezionate di un file. |
s | substitute: sostituisce una sequenza di caratteri predefinita con un’altra. |
x | xchange: scambia pattern space e hold space tra loro. |
y | yank: sostituisce un carattere predefinito con un altro. |
w | write: scrive righe in un file di testo. |
! | Negation: applica il comando sulle righe che non corrispondono all’inserimento. |
I due tipi di memoria hold space e pattern space hanno compiti differenti: pattern space descrive una memoria di lavoro a breve termine all’interno del quale si trovano i dati con i quali il comando sta lavorando. hold space è invece a lungo termine e contiene dati ai quali è possibile accedere anche quando SED è occupato a eseguire un’altra operazione.
I comandi sono estendibili con ulteriori opzioni:
Opzione | Descrizione |
= | Indica il numero di riga della riga selezionata. |
p | Emette le righe modificate. |
g | Applica il comando all’intero file. |
Aprite e chiudete i comandi con virgolette semplici per evitare che l’inserimento debba essere reinterpretato. Di per sé i caratteri non sarebbero necessari, tuttavia in questo modo contribuite a ridurre molte fonti di errore.
Espressioni regolari
Per l’utilizzo di SED è importante la comprensione di espressioni regolari. Questi caratteri servono a comunicare al comando come comportarsi in presenza di una sequenza di caratteri. Ad esempio, sono importanti le parentesi quadre e tonde:
- [ABC]: Una classe di caratteri si utilizza quando si cerca una corrispondenza all’interno di un gruppo di lettere, cifre e simboli; pertanto A, B o C.
- (ABC): Un gruppo di caratteri descrive un termine fisso; pertanto ABC in questa sequenza.
Le wildcard permettono di cercare anche solo parti di termini con le espressioni regolari. Potete applicare due varianti diverse:
- .: il punto sostituisce esattamente un carattere.
- *: l’asterisco sostituisce più caratteri a piacimento.
Inoltre le espressioni regolari vi consentono di stabilire più precisamente la frequenza di caratteri (o combinazioni di).
- ?: il punto interrogativo indica che un termine debba comparire una volta o mai.
- +: il più stabilisce che il carattere debba comparire più volte e almeno una volta.
- {0,n}: con una cifra all’interno di parentesi graffe stabilite con precisione con quanta frequenza debba comparire la combinazione di caratteri. Se inserite due valori separati da una virgola, stabilite le ripetizioni minimali e massimali.
Infine, utilizzando Linux e SED potete includere anche caratteri logici che possono ad esempio aiutarvi a creare connessioni o annidamenti.
- |: una barra verticale si trova tra due termini e simboleggia un’alternativa tra i due.
- ^: il circonflesso scritto direttamente prima di un termine lo nega; questa sequenza di caratteri non dovrebbe pertanto capitare.
Con questi caratteri modificate quindi l’inserimento all’interno del comando SED e potete portare a termine compiti complessi.
Indirizzi
In Linux SED gli inserimenti sono denominati indirizzi. Un indirizzo è quindi l’obiettivo del comando che potete indicare in modi diversi. In molti casi inserirete delle ricerche elaborate con le espressioni regolari. Tuttavia sussiste anche la possibilità di selezionare righe del file di testo. Di conseguenza annoterete gli indirizzi in modo diverso.
Nel primo esempio fate riferimento a righe concrete:
sed -n '10,50p' testo.txt
Con questo codice vengono emesse sul terminale le righe dalla 10 alla 50.
Se non sapete in quali righe trovare le informazioni con cui intendete lavorare, potete anche fare ricercare l’indirizzo. In questo caso è importante che apriate e chiudiate sempre l’espressione con una barra obliqua per separare il termine di ricerca da altre informazioni come i comandi.
sed -n 'esempio.[1-9]/p' testo.txt
Questo codice vi mostrerebbe tutte le righe indicate come esempio (o esempi) e che terminano con una cifra.
SED spiegato per mezzo di tre esempi
Il comando SED può offrire un pronto aiuto nei casi più disparati. In particolare se dovete apportare più modifiche al contempo a file di testo molto grandi, il tool dimostra la sua forza. Nei seguenti tre esempi vedrete diverse possibilità di applicazione di SED nella quotidianità di Linux.
Effettuare una ricerca all’interno di un file di testo
Il caso di applicazione più semplice è la ricerca di determinati dati in un documento. Diventa interessante è ad esempio quando si tratta di database di grandi dimensioni o anche all’interno del codice sorgente. In questo modo si trova velocemente un punto da leggere o anche modificare.
Mettiamo il caso che voleste cercare le bottiglie di vino Montepulciano all’interno della vostra notevole cantina di vini. In aggiunta, desiderate anche che venga mostrata la prima riga del database in cui sono spiegate le singole colonne. Il seguente comando vi aiuta a trovare la posizione delle bottiglie:
sed -n -e '1p' -e '/Montepulciano/p' vino.txt
Qui utilizzate due comandi uno dietro l’altro. Entrambi sono introdotti da -e. Il risultato avrà il seguente aspetto:
Scaffale Zona di produzione Vitigno Annata
1 Chieti Montepulciano 2011
2 Pescara Montepulciano 2020
3 Teramo Montepulciano 2018
Se intendete vedere solo le annate degli anni 2010, basta modificare leggermente il codice.
sed -n -e '1p' -e '/Montepulciano * 201./p' vino.txt
Scaffale Zona di produzione Vitigno Annata
1 Chieti Montepulciano 2011
3 Teramo Montepulciano 2018
In questo caso la wildcard tra vitigno e annata non è importante. Tuttavia, se il database è incorretto o se a posteriori inserite una colonna, l’indicazione rimane corretta.
Aggiungere informazioni
Con Linux e il comando SED potete anche estendere database. E per fare nuovi inserimenti non dovete aprire, modificare e salvare il file con un nuovo editor di testo. Piuttosto apportate la modifica con una sola riga di codice.
Per il nostro esempio ora supponiamo che avete ricevuto due nuove bottiglie di vino da aggiungere alla vostra collezione e di conseguenza anche al database corrispondente. Grazie a SED potete inserire una nuova riga alla fine del file di testo.
sed -i -e '$a2 Venosa Aglianico 2015' -e '$a4 Sannio Falanghina 2021' vino.txt
L’espressione regolare $ fa in modo che SED salti all’ultima riga. Il comando a provoca l’aggiunta di una nuova riga con il contenuto che segue. Utilizziamo l’opzione -i per fare in modo che il file di origine possa essere modificato direttamente, in alternativa si potrebbe creare un nuovo database:
sed -e '$a2 Venosa Aglianico 2015' -e '$a4 Sannio Falanghina 2021' vino.txt > vino1.txt
Gestire database
Se si desidera cambiare a posteriori la struttura di grandi database con molti inserimenti, manualmente è quasi impossibile. Linux offre con SED una soluzione veloce. Finora nel vostro file le singole colonne sono separate tra loro da uno spazio. Ora in questo esempio partiamo dal presupposto che vogliate sostituire lo spazio con trattino. A tal fine utilizziamo il comando s-:
sed -i -e 's/[[:space:]]/-/g' vino.txt
La g alla fine dell’indirizzo fa in modo che il comando venga applicato all’intero file.
Una situazione simile vi si prospetta se volete aggiungere ulteriori informazioni all’interno di una riga. Supponiamo ad esempio che intendiate anche annotare se avete già assaggiato il vino o meno. Prima di aggiungere ulteriori vini sconosciuti alla vostra collezione, annotate tutti quelli che conoscete già.
sed -i -e 's/$/-conosciuto/g' vino.txt
Ora l’annotazione è stata registrata a tutte le righe, compresa la prima riga in cui nominate le colonne. Per modificarlo effettuate una sostituzione nella prima riga.
sed -i -e '1s/conosciuto/assaggiato/' vino.txt
Alternative a SED
Linux SED è un comando efficiente con il quale portare a termine molte operazioni. Tuttavia, alcune possono essere compiute solo a fronte di un dispendio di tempo e lavoro. Servendovi di comandi simili potreste raggiungere gli obiettivi in modo più veloce e sicuro.
AWK
AWK si è affermato come sviluppo di SED. Anche in questo caso il comando lavora con espressioni regolari, offre però in aggiunta delle possibilità come le si conoscono in altri linguaggi di programmazione più complessi. Con AWK potete infatti creare comandi che contengono istruzioni if-else o sequenze while-do.
PERL
Mentre AWK si orienta in primo luogo ai linguaggi C, esiste anche un comando che funziona sulla base di PERL. Nonostante si possano creare anche sistemi complessi con questo linguaggio, PERL si adatta anche all’esecuzione di compiti più semplici all’interno del terminale o negli scripting Bash.
TR
Se desiderate trasformare singoli caratteri all’interno di un file di testo, l’operazione sarà più semplice utilizzando un altro tipo di comando al posto di SED, TR (abbreviazione di: translate). Questo comando è stato pensato per sostituire lettere, cifre e caratteri speciali con degli altri. In questo modo potete velocemente eliminare doppi spazi e adattare scritture in minuscolo/maiuscolo. Mentre con TR è facile portare a termine compiti semplici del genere, per compiti più complessi è meglio considerare altre soluzioni come SED.