Comando sed in Linux: sostituire testo, creare backup e verificare le modifiche

sed è un editor di flussi: legge il testo, applica regole di modifica e invia il risultato allo standard output. Per cercare e sostituire testo senza cambiare il file originale, usate una sostituzione come sed 's/red/green/' config.txt; l’opzione GNU -i modifica invece il file e richiede attenzione.

Nel normale uso per righe, sed è utile per trasformazioni ripetitive, selezione di righe e rimozione di testo dall’output. La forma di sostituzione è s/espressione/sostituzione/flag: senza flag cambia la prima corrispondenza di ogni riga, mentre g cambia tutte le corrispondenze della riga.

Sintassi e flusso dei dati

sed [opzioni] 'comando-di-modifica' [file...]

Se non indicate file, sed legge dallo standard input, quindi può seguire una pipe. Per esempio, printf 'red red\n' | sed 's/red/green/' produce green red. L’operazione modifica il flusso in uscita: non cambia il comando che lo ha generato e non salva automaticamente un file.

Le virgolette singole intorno al programma evitano che la shell interpreti caratteri come $ o la barra inversa. Sed interpreta poi la propria sintassi, comprese le espressioni regolari. Controllate man sed sul sistema usato; in GNU potete identificare la versione con sed --version.

Laboratorio completo: originale, risultato, backup e ripristino

Eseguite l’intero blocco in Bash con GNU sed. Crea ogni file necessario in una nuova directory temporanea, dentro una subshell: la directory di lavoro della shell chiamante rimane invariata. Non sovrascrive i file della directory da cui partite. Il percorso della prova viene stampato alla fine; conservatelo per esaminare i risultati e rimuovete soltanto i dati della prova quando non servono più.

(
set -eu
labdir=$(mktemp -d)
cd "$labdir"
printf 'red car\nred red\n' > config.txt
sed 's/red/green/' config.txt > first.txt
sed 's/red/green/g' config.txt > all.txt
cat config.txt first.txt all.txt
cp config.txt editable.txt
sed -i.bak 's/red/green/g' editable.txt
diff -u editable.txt.bak editable.txt || test "$?" -eq 1
cmp config.txt editable.txt.bak
cp editable.txt.bak editable.txt
cmp config.txt editable.txt
printf 'Lab files: %s\n' "$labdir"
)

La prima coppia di righe stampate è l’originale: red car e red red. Seguono green car e green red, salvate in first.txt; infine green car e green green, salvate in all.txt. La differenza dipende solo dal flag g. config.txt conserva il contenuto iniziale.

La seconda parte modifica soltanto la copia editable.txt. GNU sed con -i.bak conserva il contenuto precedente in editable.txt.bak. Il confronto diff -u mostra le modifiche; il suo stato 1 indica che ha trovato differenze, perciò il blocco lo accetta esplicitamente. Uno stato di errore diverso da 1 non viene ignorato.

I due controlli cmp non producono output quando hanno successo: il primo verifica che il backup corrisponda all’originale, il secondo che la copia ripristinata corrisponda all’originale dopo cp. Il backup rimane disponibile anche dopo il ripristino. Questi controlli confrontano il contenuto, senza dimostrare che permessi, proprietario o altri metadati siano identici.

Opzioni principali e scelta dell’output

Opzione Quando usarla
-n Disattiva la stampa automatica. Aggiungete un comando di stampa, come p, quando volete produrre righe in uscita.
-e programma Aggiunge un programma di modifica; ripetete -e per applicare più regole nell’ordine indicato.
-E Usa espressioni regolari estese, per esempio con gruppi (...) senza le barre inverse richieste dalla forma base.
-i[suffisso] In GNU, modifica il file; un suffisso unito all’opzione, come -i.bak, crea il backup. Senza suffisso non conserva una copia precedente.

Per stampare solo la seconda riga del file creato nel laboratorio, entrate nella directory indicata e usate sed -n '2p' config.txt: il risultato è red red. Per stampare entrambe le righe, sed -n '1,2p' config.txt seleziona l’intervallo inclusivo. Senza -n, un comando p si aggiunge alla stampa automatica e può duplicare le righe.

sed '2d' config.txt esclude la seconda riga dal risultato, lasciando il file intatto. Per applicare due sostituzioni in sequenza, sed -e 's/red/green/g' -e 's/green/blue/g' config.txt produce blue car e blue blue: la seconda regola vede il risultato della prima.

Espressioni regolari e caratteri speciali nella sostituzione

Il testo cercato è un’espressione regolare, non sempre una stringa letterale. Il punto . indica un carattere e .* una sequenza anche vuota di caratteri. Per cercare un punto letterale, usate \.: printf 'a.b axb\n' | sed 's/a\.b/X/g' produce X axb, mentre cercare a.b sostituisce anche axb.

Anche la parte sostitutiva ha regole proprie: & rappresenta l’intera corrispondenza, mentre \1 richiama il primo gruppo catturato. Per esempio, printf 'red\n' | sed 's/red/[&]/' produce [red]; per inserire una e commerciale letterale usate \&. Con espressioni estese, printf 'car=12\n' | sed -E 's/([a-z]+)=([0-9]+)/\2:\1/' produce 12:car.

Se i dati contengono barre oblique, potete scegliere un altro delimitatore per la sostituzione: printf '/srv/old\n' | sed 's|/srv/old|/srv/new|' produce /srv/new. Anche il delimitatore alternativo deve essere gestito se compare nei dati. Non inserite valori arbitrari dentro un programma sed senza considerare separatamente quoting della shell, espressione cercata e sostituzione.

Modificare file: controlli e limiti di -i

Prima di applicare -i a un file importante, eseguite la trasformazione sullo standard output o in un file dal nome diverso, confrontate il risultato e preparate una copia recuperabile. Una redirezione verso lo stesso file di input può troncarlo prima che sed lo legga: non usate la forma sed '...' file > file.

Non combinate -n e -i senza aver verificato quali righe vengono effettivamente stampate: se il programma non stampa nulla, la modifica può lasciare il file vuoto. Anche un backup con suffisso fisso richiede attenzione: ripetere la modifica con lo stesso suffisso può sostituire il backup precedente. Conservate separatamente una copia iniziale quando serve una possibilità di ripristino stabile.

La sintassi di -i non è uniforme fra GNU e altre implementazioni, comprese quelle BSD. Il laboratorio usa esplicitamente la forma GNU -i.bak; su un altro sistema consultate il manuale locale, senza copiare alla cieca una variante. Anche collegamenti simbolici, permessi e metadati meritano una verifica specifica prima di modificare file reali.

Il successo di sed non dimostra che il testo cercato fosse presente: una sostituzione senza corrispondenze può terminare normalmente con un risultato invariato. Controllate quindi sia lo stato del comando sia il contenuto ottenuto, come nei confronti del laboratorio.

Domanda frequente

Eseguire sed cambia il file originale?

Nel comportamento predefinito mostrato qui, no: sed scrive il testo trasformato sullo standard output. Per conservarlo, scegliete un file di destinazione diverso; per modificare l’originale con GNU sed, -i attiva la modifica e un suffisso come .bak permette di conservare il contenuto precedente. Verificate risultato e backup prima di usarli per un ripristino.

Documentazione di riferimento

La pagina di manuale del progetto GNU sed descrive opzioni, comandi e indirizzi delle righe. Il manuale completo è consultabile anche con info sed se la documentazione è installata sul sistema.