Introduzione

diff è un utility della riga di comando che consente di confrontare due file riga per riga. Può anche confrontare i contenuti delle directory.

Il comando diff è più comunemente usato per creare una patch contenente le differenze tra uno o più file che possono essere applicati usando il comando patch.

Come usare il comando diff

La sintassi per il comando diff è la seguente:

diff [OPTION]... FILES

Il comando diff può visualizzare l'output in diversi formati; normale, contestuale e unificato, che sono i più comuni. L'output include informazioni su quali righe nei file devono essere modificate in modo che diventino identiche. Se i file corrispondono, non viene prodotto alcun output.

Per salvare l'output del comando in un file, utilizzare l'operatore di reindirizzamento:

diff file1 file2 > patch

In questo articolo, utilizzeremo i seguenti due file per spiegare come funziona il comando diff:

File 1:

Ubuntu
Arch Linux
Debian
CentOS
Fedora

File 2:

Kubuntu
Ubuntu
Debian
Arch Linux
Centos
Fedora

Formato normale

Nella sua forma più semplice quando il comando diff viene eseguito su due file di testo senza alcuna opzione, produce un output nel formato normale:

diff file1 file2

L'output sarà simile al seguente:

0a1
> Kubuntu
2d2
< Arch Linux
4c4,5
< CentOS
---
> Arch Linux
> Centos

Il normale formato di output è costituito da una o più sezioni che descrivono le differenze. Ogni sezione è simile alla seguente:

change-command
< from-file-line...
---
> to-file-line...

0a1, 2d2 e 4c4,5 sono comandi di cambio. Ogni comando di modifica contiene quanto segue, da sinistra a destra:

  • Il numero di riga o l'intervallo di righe nel primo file.
  • Un carattere di cambiamento speciale.
  • Il numero di riga o l'intervallo di righe nel secondo file.

Il carattere di modifica può essere uno dei seguenti:

  • a - Aggiungi le linee.
  • c - Cambia le linee.
  • d - Elimina le righe.

Il comando change è seguito dalle righe complete rimosse con l'operatore (<) e aggiunte al file con l'operatore (>).

Spieghiamo l'output:

  • 0a1 - Aggiungi la riga 1 del secondo file all'inizio del file1 (dopo la riga 0).
  • > Kubuntu - La riga della seconda riga che viene aggiunta al primo file come descritto sopra.
  • 2d2 - Elimina la riga 2 nel primo file. Il simbolo 2 dopo d indica che se la riga non viene eliminata, verrà visualizzata sulla riga 2 nel secondo file.
  • < Arch Linux - la riga eliminata.
  • 4c4,5 - Sostituisci (cambia) la riga 5 nel primo file con le righe 4-5 del secondo file.
  • < CentOS - La riga nel primo file da sostituire.
  • --- - Separatore.
  • > Arch Linux e > Centos- Linee dal secondo file che sostituiscono la linea nel primo file.

Formato di contesto

Quando viene utilizzato il formato di output del contesto, il comando diff visualizza diverse righe di contesto attorno alle righe che differiscono tra i file.

L'opzione -c dice permette all'utility diff di produrre output nel formato di contesto:

diff -c file1 file2
*** file1	2019-11-25 21:00:26.422426523 +0100
--- file2	2019-11-25 21:00:36.342231668 +0100
***************
*** 1,6 ****
  Ubuntu
- Arch Linux
  Debian
! CentOS
  Fedora
  
--- 1,7 ----
+ Kubuntu
  Ubuntu
  Debian
! Arch Linux
! Centos
  Fedora

L'output inizia con i nomi e i timestamp se i file confrontati e una o più sezioni che descrivono le differenze. Ogni sezione è simile alla seguente:

***************
*** from-file-line-numbers ****
  from-file-line...
--- to-file-line-numbers ----
  to-file-line...
  • from-file-line-numbers e to-file-line-numbers- I numeri di riga o l'intervallo di righe separati da virgola nel primo e nel secondo file, rispettivamente.
  • from-file-line e to-file-line- Le linee che differiscono e le linee di contesto:
  • Le linee che iniziano con due spazi sono linee di contesto, le linee che sono le stesse in entrambi i file.
  • Le righe che iniziano con il simbolo meno (-) sono le righe che non corrispondono a nulla nel secondo file. Righe mancanti nel secondo file.
  • Le righe che iniziano con il simbolo più (+) sono le righe che non corrispondono a nulla nel primo file. Righe mancanti nel primo file.
  • Le righe che iniziano con il punto esclamativo (!) sono le righe modificate tra due file. Ogni gruppo di righe che iniziano con ! nel primo file ha una corrispondenza nel secondo file.

Spieghiamo le parti più importanti dell'output:

  • In questo esempio abbiamo solo una sezione che descrive le differenze.
  • *** 1,6 **** e --- 1,7 ---- ci dice l'intervallo delle linee dal primo e secondo file che sono inclusi in questa sezione.
  • Linee Ubuntu, Debian, Fedora, e l'ultima riga vuota sono gli stessi in entrambi i file. Queste linee iniziano con doppio spazio.
  • La riga - Arch Linux dal primo file corrisponde a nulla nel secondo file. Sebbene questa riga esista anche nel secondo file, le posizioni sono diverse.
  • La riga + Kubuntu del secondo file non corrisponde a nulla nel primo file.
  • La riga ! CentOS dal primo file e le righe ! Arch Linux e ! CentOS dal secondo file vengono modificate tra i file.

Per impostazione predefinita, il numero delle linee di contesto è impostato su tre. Per specificare un altro numero, utilizzare l'opzione -C( --contexts):

diff -C 1 file1 file2
*** file1	2019-11-25 21:00:26.422426523 +0100
--- file2	2019-11-25 21:00:36.342231668 +0100
***************
*** 1,5 ****
  Ubuntu
- Arch Linux
  Debian
! CentOS
  Fedora
--- 1,6 ----
+ Kubuntu
  Ubuntu
  Debian
! Arch Linux
! Centos
  Fedora

Formato unificato

Il formato di output unificato è una versione migliorata del formato di contesto e produce un output più piccolo.

Utilizzare l'opzione -u per indicare al comando diff di stampare l'output nel formato unificato:

diff -u file1 file2
--- file1	2019-11-25 21:00:26.422426523 +0100
+++ file2	2019-11-25 21:00:36.342231668 +0100
@@ -1,6 +1,7 @@
+Kubuntu
 Ubuntu
-Arch Linux
 Debian
-CentOS
+Arch Linux
+Centos
 Fedora

L'output inizia con i nomi e i timestamp dei file e una o più sezioni che descrivono le differenze. Ogni sezione ha la forma seguente:

***************
@@ from-file-line-numbers to-file-line-numbers @@
 line-from-files...
  • @@ from-file-line-numbers to-file-line-numbers @@ - Il numero o l'intervallo delle righe dal primo e dal secondo file inclusi in questa sezione.
  • line-from-files - Le linee che differiscono e le linee di contesto:
  • Le linee che iniziano con due spazi sono linee di contesto, le linee che sono le stesse in entrambi i file.
  • Le righe che iniziano con il simbolo meno (-) sono le righe che vengono rimosse dal primo file.
  • Le righe che iniziano con il simbolo più (+) sono le righe aggiunte dal primo file.

Ignora il caso

Come è possibile notare negli esempi precedenti, il comando diff fa distinzione tra maiuscole e minuscole per impostazione predefinita.

Usa l'opzione -i per dire al comando diff di ignorare il caso:

diff -ui file1 file2
--- file1	2019-11-25 21:00:26.422426523 +0100
+++ file2	2019-11-25 21:00:36.342231668 +0100
@@ -1,6 +1,7 @@
+Kubuntu
 Ubuntu
-Arch Linux
 Debian
+Arch Linux
 CentOS
 Fedora

Conclusione

Il confronto dei file di testo per le differenze è una delle attività più comuni per gli amministratori di sistemi Linux.

Il comando diff confronta i file riga per riga. Per ulteriori informazioni, digitare il seguente comando nel terminale:

man diff