Comando sed: sostituzione di stringhe, eliminazione di righe e opzione -i

Ambiente di testFamiglia RHELAlmaLinux 9.8account rootVerificato il 2026-10-28

Il comando sed è uno strumento Linux che legge un file riga per riga ed esegue sostituzioni, eliminazioni e inserimenti, così puoi modificare i valori di un file di configurazione senza aprire un editor. Eseguendo sed su una copia del file wp-config.php di WordPress su un server AlmaLinux 9, abbiamo potuto cambiare il nome del database conservando l'originale con -i.bak.

I messaggi di errore di questo articolo sono riportati così come stampati con una locale inglese.

1️⃣ Uso di base del comando sed e sostituzione con s

Il comando s, il più usato, sostituisce le stringhe nel formato [s/stringa da cercare/nuova stringa/]. Sostituisce solo la prima occorrenza di una riga.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'
https://example.com http://example.com/blog

Per sostituire tutte le occorrenze della riga, aggiungi il flag g alla fine.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'
https://example.com https://example.com/blog

Se aggiungi un nome di file alla fine, sed legge quel file e stampa il risultato modificato. In una copia di wp-config-sample.php di WordPress chiamata wp-config.php abbiamo cambiato il valore di DB_USER e controllato solo quella riga con grep.

sed 's/username_here/wp_user/' wp-config.php | grep DB_USER
define( 'DB_USER', 'wp_user' );

Poiché il valore è cambiato nell'output, è facile pensare che sia cambiato anche il file, ma senza opzioni sed stampa il risultato solo a schermo e lascia il file originale così com'è. Cercando di nuovo la stessa riga nel file, il valore iniziale era ancora lì.

grep DB_USER wp-config.php
define( 'DB_USER', 'username_here' );

Per modificare anche il file originale, usa l'opzione -i di 4️⃣.

2️⃣ Selezionare righe in sed per numero e pattern (-n, p)

Senza indirizzo, il comando s si applica a tutte le righe, quindi per lavorare solo su alcune scrivi davanti al comando un numero di riga o un pattern come indirizzo. -n disattiva la stampa automatica e p stampa le righe selezionate. Insieme mostrano solo la riga 23.

sed -n '23p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

Unendo due numeri di riga con una virgola compare quell'intervallo. Le righe da 23 a 32 sono la sezione con le impostazioni di nome del database, utente, password e host.

sed -n '23,32p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

/** Database username */
define( 'DB_USER', 'username_here' );

/** Database password */
define( 'DB_PASSWORD', 'password_here' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

Se al posto del numero di riga scrivi un pattern tra barre, vengono selezionate tutte le righe che contengono quel pattern.

sed -n '/DB_/p' wp-config.php
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

Il comando [=] stampa il numero della riga selezionata. L'indirizzo $ indica l'ultima riga, quindi con [$=] puoi vedere il numero totale di righe del file.

sed -n '/DB_HOST/=' wp-config.php
32
sed -n '$=' wp-config.php
102

L'indirizzo può stare anche davanti al comando s. Qui sotto c'è il risultato della modifica di localhost solo alla riga 32, con la stampa della sola riga cambiata tramite il flag p.

sed -n '32s/localhost/127.0.0.1/p' wp-config.php
define( 'DB_HOST', '127.0.0.1' );

Eseguendo p senza -n, la riga selezionata è comparsa un'altra volta. sed legge le righe una alla volta nello spazio dei pattern, esegue i comandi e poi stampa automaticamente lo spazio dei pattern, quindi la riga 2 stampata da p ricompare con la stampa automatica.

sed '2p' wp-config.php | head -n 4
<?php
/**
/**
 * The base configuration for WordPress

Questo modo di leggere ed elaborare una riga alla volta è come un nastro trasportatore di fabbrica che porta i pezzi uno alla volta sul banco, li lavora e passa al successivo.

Nel diagramma qui sotto puoi confrontare passo per passo che cosa stampa ogni comando per ogni riga.

🧭 Spazio dei pattern di sed e stampa automatica: p e d sulla riga 2
Diagramma esplicativo
⚙️ Comando
$ sed '2p'-n '2p''2d' wp-config.php
Riga lettaEsecuzione del comando e output
Riga 1 → spazio dei pattern<?php
➜
Diversa dall'indirizzo 2: nessun comandoStampa automatica 1 voltaNessun output per -n
Riga 2 → spazio dei pattern/**
➜
Uguale all'indirizzo 2: esegue pUguale all'indirizzo 2: esegue d1 volta da p + 1 volta automaticaSolo 1 volta da pSvuota lo spazio dei pattern e passa alla riga successiva
Riga 3 → spazio dei pattern * The base configuration for WordPress
➜
Diversa dall'indirizzo 2: nessun comandoStampa automatica 1 voltaNessun output per -n
🖥️ Che cosa compare a schermo (righe 1~3)
<?php/**/** * The base configuration for WordPress
p stampa ancora una volta lo spazio dei pattern, quindi senza -n la riga 2 compare due volte.
-n disattiva la stampa automatica, quindi solo la riga 2 selezionata da p compare una volta.
d svuota lo spazio dei pattern e passa alla riga successiva, quindi la riga 2 non viene stampata automaticamente.

3️⃣ Eliminare e inserire righe con il comando sed (d, i, a)

d elimina le righe selezionate. Per vedere la configurazione di esempio di nginx qui sotto senza le righe di commento, seleziona con il pattern [^ *#] le righe che iniziano con # o che hanno solo spazi prima di #.

cat example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
sed '/^ *#/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Unendo i comandi con un punto e virgola viene eliminato anche [^$], che indica una riga vuota. Le due righe vuote rimaste dopo aver tolto i commenti sono sparite e sono rimaste solo le righe di configurazione.

sed '/^ *#/d; /^$/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

i inserisce testo prima della riga selezionata e a lo inserisce dopo. Il risultato dell'inserimento di una riga di commento prima della riga 1 è qui sotto.

sed '1i # managed by sed' example.conf | head -n 3
# managed by sed
# example.com
server {

È facile pensare che un testo rientrato dopo a mantenga il rientro, ma GNU sed salta gli spazi subito dopo a e inserisce solo il testo.

sed '/index index.php/a    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Per mantenere il rientro, aggiungi una barra rovesciata dopo a. Dallo spazio dopo la barra rovesciata in poi tutto entra come testo.

sed '/index index.php/a\    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

c sostituisce per intero la riga selezionata. Qui sotto ci sono le prime quattro righe del risultato del passaggio della riga listen 80 a 8080.

sed '/listen 80;/c\    listen 8080;' example.conf | head -n 4
# example.com
server {
    listen 8080;
    server_name example.com www.example.com;

4️⃣ Modificare direttamente i file con sed -i e nome del backup

-i salva il risultato nel file originale invece di mostrarlo a schermo. Il testo attaccato subito dopo -i viene aggiunto alla fine del nome del file di backup. wp-config.php e gli altri file letti dal sito conviene modificarli con -i.bak, conservando l'originale.

cp wp-config-sample.php wp-config.php
sed -i.bak 's/database_name_here/wordpress_db/' wp-config.php

Con -i a schermo non compare nulla, quindi controlla i file con ls -l.

ls -l wp-config.php*
-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bak

Il file modificato e il file .bak ora stanno fianco a fianco. La dimensione è scesa di 6 byte perché database_name_here è diventato il più corto wordpress_db. Confrontando i due file con diff si vede solo la riga cambiata.

diff wp-config.php.bak wp-config.php
23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );

La riga cambiata è l'unica riga DB_NAME, alla riga 23.

Se ci sono più valori da cambiare, concatena gli script con -e ed eseguili in una volta.

sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.php
grep -n -e DB_USER -e DB_PASSWORD wp-config.php
26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );

Se scrivi -i ed -e attaccati come [-ie], la e viene letta come parte del nome del backup, ed è comparso un file wp-config.phpe come qui sotto.

sed -ie 's/127.0.0.1/localhost/' wp-config.php
ls wp-config.php*
wp-config.php
wp-config.php.bak
wp-config.phpe

-i scrive il contenuto modificato in un nuovo file e poi lo rinomina con il nome originale, quindi il numero di inode del file cambia tra prima e dopo l'esecuzione.

ls -i wp-config.php
207618887 wp-config.php
sed -i 's/localhost/127.0.0.1/' wp-config.php
ls -i wp-config.php
207618883 wp-config.php

Il numero di inode, 207618887 prima dell'esecuzione, è diventato 207618883.

Se il file non esiste o dimentichi il nome del file, sed termina con l'errore qui sotto e nessun file viene modificato.

sed -i 's/x/y/' no-such.php
sed: can't read no-such.php: No such file or directory
sed -i 's/x/y/'
sed: no input files

5️⃣ Espressioni regolari di sed, cambio del delimitatore e opzioni

🔲 Espressioni regolari e cambio del delimitatore

Se cambi un valore che contiene barre, come un percorso, il delimitatore del comando s si confonde con le barre del valore, quindi ogni barra del valore richiede una barra rovesciata.

sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf
    root /srv/www/example.com;

Il carattere subito dopo s diventa il delimitatore, quindi passando a |, assente dal valore, ottieni lo stesso risultato senza barre rovesciate.

sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf
    root /srv/www/example.com;

Il punto (.) in un pattern corrisponde a un qualsiasi carattere. Qui sotto c'è il risultato di un pattern che cerca example.com e ha modificato anche exampleXcom.

echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'
test.org test.org

Per cercare un punto letterale, mettici davanti una barra rovesciata.

echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'
exampleXcom test.org

Una parte tra parentesi si richiama nella nuova stringa con [\1]. Con -E puoi usare parentesi e + senza barre rovesciate. Qui sotto c'è il risultato che lascia il numero dopo listen e aggiunge default_server.

sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

Senza -E, lo stesso script legge le parentesi come testo e compare un errore perché non c'è un gruppo da richiamare. Per lavorare senza -E, metti una barra rovesciata davanti alle parentesi e a +.

sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
sed: -e expression #1, char 46: invalid reference \1 on `s' command's RHS
sed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

[&] nella nuova stringa indica tutto il testo che corrisponde al pattern, quindi puoi aggiungere # davanti alla parte trovata e trasformare la riga in un commento.

sed -n 's/server_name .*;/# &/p' example.conf
    # server_name example.com www.example.com;

🔲 Opzioni del comando sed

📌 Opzioni principali: risultati di questo articolo

OpzioneCompitoRisultato in questo articolo
-nDisattiva la stampa automatica e stampa solo le righe selezionate con psed -n '23p' mostra solo la riga 23; senza -n, 2p stampa la riga 2 due volte
-iSalva il risultato nel file originale invece che a schermo (il testo subito dopo va alla fine del nome del backup)-i.bak crea wp-config.php.bak; il numero di inode cambia dopo l'esecuzione
-eConcatena più script e li esegue in una voltaDB_USER e DB_PASSWORD cambiano in una volta; attaccati come -ie, compare il backup wp-config.phpe
-EUsa le espressioni regolari estese (senza barre rovesciate per parentesi e +)Stampa listen 80 default_server;; lo stesso script senza -E dà l'errore [invalid reference]
--follow-symlinksInsieme a -i, modifica il file originale a cui punta il linkSenza l'opzione, un file normale prende il posto del link e l'originale resta uguale; con l'opzione cambia il valore originale

📎 Altre opzioni: secondo il manuale ufficiale

OpzioneCompito
-fLegge lo script da un file e lo esegue
-rEspressioni regolari estese, come -E (-E è più portabile)
-sTratta ogni file separatamente invece che come un unico flusso continuo
-zSepara le righe con il carattere nullo invece del ritorno a capo
-uLegge l'input a piccole quantità e scarica l'output più spesso
--posixDisattiva tutte le estensioni GNU
--debugStampa lo svolgimento dell'esecuzione in forma estesa

🔲 Simulatore del comando sed

La cartella di lavoro del simulatore qui sotto contiene una copia di wp-config.php ed example.conf. Puoi digitare i comandi visti finora e controllare con ls -l e diff i file modificati da -i.

Simulatore del comando sedGNU sed
[root@server work]#
Con i tasti ↑↓ richiami i comandi digitati prima.

🔢 FAQ & contenuti consigliati

wp-config-sample.php di WordPress ha fine riga CRLF, quindi subito prima della fine riga c'è un [\r] invisibile. [/false );$/] non ha stampato nessuna riga, mentre in una copia in cui [\r] è stato tolto con [s/\r$//] lo stesso pattern ha trovato la riga WP_DEBUG.

-i crea un nuovo file normale al posto del link e salva lì, quindi l'originale a cui puntava il link non è cambiato. Per modificare il file originale, indica anche [--follow-symlinks]. In questo caso il link è rimasto e il valore originale è cambiato.

Anche una variabile impostata con NEW=wp_user non viene espansa dalla shell tra virgolette semplici, e [$NEW] entra come testo letterale. Con lo script tra virgolette doppie, la shell ha espanso prima la variabile e wp_user è entrato al posto di [$NEW].

🧭 Contenuti consigliati sui comandi di testo 9 articoli · 2 riferimenti
🗂️ Comandi per visualizzare · modificare testo
📄 Comando grep 📄 Comando sort 📄 Comando uniq 📄 Comando tee 📄 Comando sed
📄 Comando cat 📄 Comando less 📄 Comandi head · tail 📄 Comandi vi · vim

ℹ️ Informativa sull'affiliazione
I contenuti di questo sito includono link di affiliazione. Se un visitatore acquista un prodotto o un servizio tramite uno di questi link, il sito riceve una commissione dal venditore. In questo processo l'importo pagato dall'acquirente (durante le promozioni l'importo scende↓) non aumenta. Prezzi, sconti e disponibilità indicati si riferiscono al momento della stesura e possono differire da quelli reali: prima di acquistare verifica sempre presso il venditore. I prodotti vengono scelti e valutati secondo criteri propri, e le commissioni non influiscono sull'ordine di presentazione né sul contenuto delle valutazioni.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Dimostra di essere umano: 3   +   5   =