Comando diff: confronto di file, formato patch di diff -u e opzioni
Il comando diff è un comando Linux che confronta due file riga per riga e mostra solo le righe diverse. Confrontando con diff un file vecchio e uno nuovo che imitano la configurazione di un server web, i tre punti modificati sono comparsi nelle tre righe 2,3c2,3, 5d4 e 6a6, e nel file di patch salvato con l'opzione -u le stesse modifiche erano organizzate con segni meno e più.
I nomi e il contenuto dei file nell'output qui sotto e la cartella di lavoro /root/work sono valori di esempio. Tutti i file confrontati sono piccoli file creati per la prova.
1️⃣ Uso di base del comando diff e lettura dell'output
La forma di base del comando è diff, opzioni, primo file e secondo file, in quest'ordine. Mostra, con i numeri di riga, quali righe vanno modificate, eliminate o aggiunte perché il primo file diventi uguale al secondo.
I due file usati per il confronto sono file di sei righe che imitano la configurazione di un server web.
cd /root/workcat config-old.conf# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warncat config-new.conf# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache onI due file sono stati confrontati senza opzioni.
diff config-old.conf config-new.conf2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache onecho $?1Nell'output si alternano righe di posizione e righe di contenuto. La lettera centrale di una riga di posizione è c per modificare, d per eliminare e a per aggiungere; a sinistra della lettera ci sono i numeri di riga del primo file, a destra quelli del secondo. Se c'è una differenza, il codice di uscita è 1.
| Output | Significato |
|---|---|
| 2,3c2,3 | Modifica le righe 2–3 del primo file nelle righe 2–3 del secondo file (change) |
| 5d4 | Elimina la riga 5 del primo file (delete). Una volta eliminata, si allinea dopo la riga 4 del secondo file |
| 6a6 | Aggiunge la riga 6 del secondo file dopo la riga 6 del primo file (add) |
| < riga | Riga presente nel primo file |
| > riga | Riga presente nel secondo file |
| --- | Confine tra il lato del primo file e quello del secondo file nelle righe modificate (c) |
Confrontando file con lo stesso contenuto non viene mostrato nulla e il comando termina con il codice di uscita 0.
diff config-old.conf config-copy.confecho $?0Indicando un file che non esiste compare un messaggio di errore e il codice di uscita è 2.
diff config-old.conf nosuch.confdiff: nosuch.conf: No such file or directoryecho $?2In uno script, questi tre valori permettono di distinguere uguale, diverso ed errore.
2️⃣ Formato unificato di diff -u e file di patch
L'output predefinito mostra solo le righe modificate, quindi in un file di configurazione con centinaia di righe è difficile capire vicino a quale impostazione si trovano. Con -u l'output è nel formato unificato (unified), che raggruppa fino a tre righe prima e dopo le righe modificate.
diff -u config-old.conf config-new.conf--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache onLe due righe di intestazione (---, +++) mostrano il nome e l'ora di modifica dei due file, e la riga @@ -1,6 +1,6 @@ è un blocco (hunk) che raggruppa 6 righe a partire dalla riga 1 del primo file e 6 righe a partire dalla riga 1 del secondo. Nelle righe sotto, un - all'inizio indica una riga eliminata dal primo file, un + una riga aggiunta al secondo file e uno spazio una riga uguale nei due file.
-c è il formato contestuale (context). Mostra separatamente il blocco del primo file e quello del secondo, con un punto esclamativo davanti alle righe modificate, un segno meno sulle righe eliminate e un segno più su quelle aggiunte.
diff -c config-old.conf config-new.conf*** config-old.conf Thu Oct 29 02:24:50 2026
--- config-new.conf Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
# app config
! listen 80
! server_name example.com
root /var/www/html
- gzip off
log_level warn
--- 1,6 ----
# app config
! listen 443
! server_name example.com www.example.com
root /var/www/html
log_level warn
+ cache onCon le stesse modifiche, -c è risultato più lungo di -u perché le righe invariate compaiono una volta in ciascuno dei due blocchi.
Salvando l'output di -u in un file, quel file è già il file di patch. Anche inviando l'output a un file, il codice di uscita di diff resta 1.
diff -u config-old.conf config-new.conf > /root/work/config.patchecho $?1cat /root/work/config.patch--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache onIl contenuto del file salvato è uguale al risultato di -u mostrato a schermo. Passando questo file al comando patch, il primo file può assumere lo stesso contenuto del secondo.
3️⃣ Opzioni di diff e come ignorare spazi e maiuscole
Ricopiando a mano una configurazione nascono righe con lo stesso contenuto che differiscono solo per maiuscole o spazi. Nella seconda coppia di file di esempio la L maiuscola della prima riga diventa minuscola, uno spazio della seconda riga diventa due e viene aggiunta una riga vuota.
cat case-a.txtListen 80
ServerName example.com
DocumentRoot /var/www/htmlcat case-b.txtlisten 80
ServerName example.com
DocumentRoot /var/www/htmldiff case-a.txt case-b.txt1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName example.com
>Nel confronto senza opzioni anche le righe 1–2, che hanno lo stesso significato, risultano righe modificate. Ignorando le maiuscole con -i, la riga Listen sparisce e resta solo la riga 2 del primo file.
diff -i case-a.txt case-b.txt2c2,3
< ServerName example.com
---
> ServerName example.com
>Aggiungendo -w vengono ignorati tutti gli spazi all'interno della riga, così anche la riga ServerName diventa uguale e resta solo la riga vuota aggiunta alla riga 3. Mettendo -b, che ignora solo il numero di spazi, al posto di -w, con questi file il risultato è stato lo stesso.
diff -i -w case-a.txt case-b.txt2a3
>Aggiungendo anche -B vengono ignorate pure le differenze di righe vuote, e il comando è terminato senza output con il codice di uscita 0.
diff -i -w -B case-a.txt case-b.txtecho $?0Per vedere i due file affiancati, a sinistra e a destra, si usa -y. La larghezza predefinita è di 130 colonne, quindi è stata ridotta con -W 70.
diff -y -W 70 config-old.conf config-new.conf# app config # app config
listen 80 | listen 443
server_name example.com | server_name example.com www.ex
root /var/www/html root /var/www/html
gzip off <
log_level warn log_level warn
> cache onLa barra verticale (|) al centro indica una riga modificata, < una riga presente solo nel primo file e > una riga presente solo nel secondo. Riducendo la larghezza, le righe lunghe vengono troncate. La riga server_name è comparsa a destra solo fino a www.ex.
Aggiungendo --suppress-common-lines le righe uguali vengono tolte e restano solo quelle diverse.
diff -y --suppress-common-lines -W 70 config-old.conf config-new.conflisten 80 | listen 443
server_name example.com | server_name example.com www.ex
gzip off <
> cache onPer verificare solo se i file sono uguali o diversi, e non il contenuto delle differenze, si usa -q. Quando i file sono uguali -q non mostra nulla, quindi per ottenere una riga che dice che sono uguali si usa -s.
diff -q config-old.conf config-new.confFiles config-old.conf and config-new.conf differdiff -s config-old.conf config-copy.confFiles config-old.conf and config-copy.conf are identicalLe opzioni sono raccolte nelle due schede qui sotto.
| Opzione | Copia | Descrizione |
|---|---|---|
| -u, --unified | Mostra nel formato unificato, che raggruppa fino a tre righe prima e dopo le righe modificate | |
| -c, --context | Formato contestuale, che mostra separatamente il blocco del primo file e quello del secondo | |
| -i, --ignore-case | Ignora le differenze tra maiuscole e minuscole | |
| -w, --ignore-all-space | Ignora tutti gli spazi all'interno della riga | |
| -b, --ignore-space-change | Ignora solo le differenze nel numero di spazi | |
| -B, --ignore-blank-lines | Ignora le differenze di righe vuote | |
| -y, --side-by-side | Mostra i due file affiancati, a sinistra e a destra | |
| -W, --widthNUM | Imposta la larghezza dell'output affiancato. Il valore predefinito è 130 colonne | |
| --suppress-common-lines | Nell'output affiancato toglie le righe uguali e mostra solo quelle diverse | |
| -q, --brief | Mostra solo se sono uguali o diversi. Se sono uguali non mostra nulla | |
| -s, --report-identical-files | Mostra una riga che dice che sono uguali quando i due file sono uguali | |
| -r, --recursive | Confronta anche i file nelle sottocartelle |
| Opzione | Copia | Descrizione |
|---|---|---|
| -U, --unifiedNUM | Imposta quante righe prima e dopo mostrare insieme nel formato unificato. Il valore predefinito è 3 | |
| -N, --new-file | Tratta come file vuoto il file che manca da un lato | |
| -x, --excludePAT | Esclude dal confronto i file il cui nome corrisponde al pattern | |
| -I, --ignore-matching-linesRE | Ignora la differenza se tutte le righe modificate corrispondono all'espressione regolare | |
| -Z, --ignore-trailing-space | Ignora gli spazi a fine riga | |
| -E, --ignore-tab-expansion | Ignora le differenze dovute alla conversione delle tabulazioni in spazi | |
| -a, --text | Tratta tutti i file come testo | |
| --strip-trailing-cr | Toglie il ritorno a capo del carrello a fine riga prima del confronto | |
| --colorWHEN | Colora l'output. WHEN è never, always o auto | |
| -v, --version | Stampa le informazioni sulla versione |
🔲 Simulatore del comando diff
Nel simulatore qui sotto si può digitare diff direttamente con i file di esempio dell'articolo. Si può salvare un file di patch con -u o confrontare con -i -w -B e -rq, e aggiungendo una riga a config-new.conf e ripetendo il confronto compare il risultato modificato.
4️⃣ Confrontare cartelle con diff -r
Per confrontare più file in una volta, ad esempio prima e dopo la pubblicazione dei file di un sito, si scrivono nomi di cartella al posto dei file. Le cartelle di esempio site-v1 e site-v2 contengono entrambe index.html e una cartella css, mentre about.html e contact.html si trovano solo da un lato.
diff site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>Confrontando cartelle senza opzioni, i file presenti solo da un lato compaiono come righe [Only in] e le sottocartelle solo come righe [Common subdirectories], senza che i file al loro interno vengano confrontati. Per index.html, presente con lo stesso nome nelle due cartelle, le differenze vengono mostrate sotto la riga [diff site-v1/index.html site-v2/index.html]. Con -r viene mostrato anche il valore di colore modificato in style.css, nella cartella css.
diff -r site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>In una cartella con molti file, prima si controlla con -rq l'elenco dei file modificati e poi si confrontano di nuovo con diff solo i file necessari.
diff -rq site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ🔢 FAQ & contenuti consigliati
Linux · Testo
Comando grep di Linux
Come usare grep per trovare e mostrare solo le righe che contengono la stringa cercata in un file di testo, come un file di log.
Linux · Testo
Comando sort di Linux: ordinare i file
Opzioni ed esempi di sort per ordinare il contenuto di un file in ordine alfabetico, crescente o decrescente.
Linux · Testo
Comando uniq di Linux
Come usare uniq per tenere una sola delle righe doppie e contare con -c quante volte si ripetono.
ℹ️ 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.