Comando diff: confronto di file, formato patch di diff -u e opzioni

Ambiente di testFamiglia RHELAlmaLinux 9.8account root

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/work
cat config-old.conf
# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warn
cat config-new.conf
# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache on

I due file sono stati confrontati senza opzioni.

diff config-old.conf config-new.conf
2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache on
echo $?
1

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

OutputSignificato
2,3c2,3Modifica le righe 2–3 del primo file nelle righe 2–3 del secondo file (change)
5d4Elimina la riga 5 del primo file (delete). Una volta eliminata, si allinea dopo la riga 4 del secondo file
6a6Aggiunge la riga 6 del secondo file dopo la riga 6 del primo file (add)
< rigaRiga presente nel primo file
> rigaRiga 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.conf
echo $?
0

Indicando un file che non esiste compare un messaggio di errore e il codice di uscita è 2.

diff config-old.conf nosuch.conf
diff: nosuch.conf: No such file or directory
echo $?
2

In 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 on

Le 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 on

Con 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.patch
echo $?
1
cat /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 on

Il 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.txt
Listen 80
ServerName example.com
DocumentRoot /var/www/html
cat case-b.txt
listen 80
ServerName  example.com

DocumentRoot /var/www/html
diff case-a.txt case-b.txt
1,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.txt
2c2,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.txt
2a3
>

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.txt
echo $?
0

Per 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 on

La 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.conf
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
gzip off                          <
                                  >     cache on

Per 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.conf
Files config-old.conf and config-new.conf differ
diff -s config-old.conf config-copy.conf
Files config-old.conf and config-copy.conf are identical

Le opzioni sono raccolte nelle due schede qui sotto.

OpzioneCopiaDescrizione
-u, --unifiedMostra nel formato unificato, che raggruppa fino a tre righe prima e dopo le righe modificate
-c, --contextFormato contestuale, che mostra separatamente il blocco del primo file e quello del secondo
-i, --ignore-caseIgnora le differenze tra maiuscole e minuscole
-w, --ignore-all-spaceIgnora tutti gli spazi all'interno della riga
-b, --ignore-space-changeIgnora solo le differenze nel numero di spazi
-B, --ignore-blank-linesIgnora le differenze di righe vuote
-y, --side-by-sideMostra i due file affiancati, a sinistra e a destra
-W, --widthNUMImposta la larghezza dell'output affiancato. Il valore predefinito è 130 colonne
--suppress-common-linesNell'output affiancato toglie le righe uguali e mostra solo quelle diverse
-q, --briefMostra solo se sono uguali o diversi. Se sono uguali non mostra nulla
-s, --report-identical-filesMostra una riga che dice che sono uguali quando i due file sono uguali
-r, --recursiveConfronta anche i file nelle sottocartelle
OpzioneCopiaDescrizione
-U, --unifiedNUMImposta quante righe prima e dopo mostrare insieme nel formato unificato. Il valore predefinito è 3
-N, --new-fileTratta come file vuoto il file che manca da un lato
-x, --excludePATEsclude dal confronto i file il cui nome corrisponde al pattern
-I, --ignore-matching-linesREIgnora la differenza se tutte le righe modificate corrispondono all'espressione regolare
-Z, --ignore-trailing-spaceIgnora gli spazi a fine riga
-E, --ignore-tab-expansionIgnora le differenze dovute alla conversione delle tabulazioni in spazi
-a, --textTratta tutti i file come testo
--strip-trailing-crToglie il ritorno a capo del carrello a fine riga prima del confronto
--colorWHENColora l'output. WHEN è never, always o auto
-v, --versionStampa 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.

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

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-v2
Only 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-v2
Only 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-v2
Only 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

cmp confronta due file byte per byte e mostra solo la prima posizione in cui differiscono. Confrontando con cmp i due file di configurazione dell'articolo, il risultato è stato l'unica riga [config-old.conf config-new.conf differ: char 21, line 2]. Si usa per verificare se sono uguali file compressi o immagini, per i quali un confronto riga per riga non ha senso.

Al comando patch si passano il file originale e il file di patch, in quest'ordine ([patch config-old.conf config.patch]). patch modifica il file originale sul posto, quindi conviene scrivere il risultato in un altro file con -o oppure applicarlo prima a una copia.

L'opzione --color[=WHEN] aggiunge il colore, e al posto di WHEN si mette never, always o auto. --color senza valore equivale ad auto e aggiunge il colore solo quando l'output va a un terminale; per mantenere il colore anche passando l'output a un altro comando come less si usa --color=always.

ℹ️ 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: 1   +   1   =