Nella prima parte di questa serie di tutorial sul comando diff, abbiamo discusso le basi del comando, incluso come funziona e come può essere compreso l'output che produce. Anche se c'è sicuramente un po' di curva di apprendimento coinvolta con questa utilità della riga di comando, vale la pena imparare soprattutto se il tuo lavoro quotidiano prevede l'esecuzione di attività relative ai file su macchine Linux solo CLI.
Supponendo che tu conosca già l'utilizzo di base del comando diff, in questo tutorial discuteremo le varie opzioni della riga di comando fornite dallo strumento, attraverso alcuni esempi di facile comprensione.
Ma prima di procedere, tieni presente che tutti gli esempi in questo tutorial sono stati testati su Ubuntu 14.04 con la versione Bash 4.3.11(1) e la versione diff 3.3.
Opzioni comando Diff
1. Segnala quando i file sono identici
Per impostazione predefinita, quando il comando diff rileva che i file confrontati sono identici, non produce alcun output.
$ diff file1 file2
$
Ma esiste un'opzione della riga di comando (-s) utilizzando la quale puoi forzare il comando a segnalare questo nell'output:
$ diff -s file1 file2
Files file1 and file2 are identical
2. Contesto copiato e contesto unificato
Questi sono fondamentalmente due formati diversi in cui il comando diff può produrre il suo output. Il contesto copiato viene abilitato utilizzando l'opzione della riga di comando -c, mentre il contesto unificato viene abilitato utilizzando -u. Di seguito è riportato un esempio del primo:
$ diff -c file1 file2
*** file1 2016-12-29 09:36:47.175597647 +0530
--- file2 2016-12-29 09:19:55.799558326 +0530
***************
*** 1,3 ****
Hi
! Helllo
Bye
--- 1,3 ----
Hi
! Hello
Bye
Quindi, nel formato di output del contesto copiato, le diverse righe sono indicate da un punto esclamativo (!).
Ed ecco l'esempio del formato del contesto unificato:
$ diff -u file1 file2
--- file1 2016-12-29 09:36:47.175597647 +0530
+++ file2 2016-12-29 09:19:55.799558326 +0530
@@ -1,3 +1,3 @@
Hi
-Helllo
+Hello
Bye
In questo formato di output, +
e -
i simboli prima delle righe indicano le versioni della riga diversa: '-' quando la riga nel file1
manca dal file2
, '+' quando riga nel file2
è stato aggiunto al file1.
3. Genera uno script 'ed'
Il comando diff è anche in grado di produrre comandi che l'editor 'ed' può utilizzare per convertire il file originale (file1 nei nostri esempi qui) nel nuovo file (file2). Ecco come farlo:
Supponiamo che file1 e file2 contengano la seguente modifica:
$ diff file1 file2
2c2
< Helllo
---
> Hello
Ora, usa l'opzione della riga di comando -e per produrre l'output che l'editor 'ed' comprende e reindirizza quell'output in un file:
diff -e file1 file2 > out
Ecco cosa fuori contiene in questo caso:
2c
Hello
.
Quello che devi fare dopo è aggiungere il comando 'w' alla fine di out file.
2c
Hello
.
w
Ora, esegui il seguente comando:
ed - file1 < out
E vedrai che file1 e file2 ora sono identici.
$ diff file1 file2
$
Per ulteriori informazioni su questa funzionalità, vai qui.
4. Produci output in due colonne
Normalmente, il comando diff produce l'output nel modo seguente:
$ diff file1 file2
2c2
< Helllo
---
> Hello
Ma esiste un'opzione della riga di comando (-y) che dirige diff per produrre output in due colonne separate. Ecco un esempio:
$ diff -y file1 file2
Hi Hi
Helllo | Hello
Bye Bye
Come puoi vedere, questo formato di output utilizza un '|' per indicare le linee che differiscono.
5. Nascondi le linee comuni
Se osservi l'output mostrato nella sezione precedente (punto 4 sopra), noterai che con -y opzione della riga di comando, diff - nell'output - produce anche righe comuni. Nel caso in cui sia necessario eliminare queste linee identiche, puoi utilizzare --suppress-common-lines opzione.
[email protected]:~$ diff -y --suppress-common-lines file1 file2
Helllo | Hello
6. Mostra la funzione C in cui ogni modifica è
Nei casi in cui utilizzi diff per confrontare due file di linguaggio C, è disponibile un'opzione della riga di comando (-p) che indica all'utilità di mostrare esattamente in quale funzione C si trova ciascuna modifica. Ad esempio, supponiamo che questi siano i due file C:
file1.c:
#include<stdio.h>
void compare(float x, float y)
{
if(x == y) // incorrect way
{
printf("\n EQUAL \n");
}
}
int main(void)
{
compare(1.234, 1.56789);
return 0;
}
file2.c:
#include<stdio.h>
void compare(float x, float y)
{
if(x == y)
{
printf("\n EQUAL \n");
}
}
int main(void)
{
compare(1.234, 1.56789);
return 0;
}
Ecco l'output quando entrambi i file vengono confrontati normalmente:
$ diff file1.c file2.c
5c5
< if(x == y) // incorrect way
---
> if(x == y)
Ed ecco l'output, quando i file vengono confrontati usando -p opzione:
$ diff -p file1.c file2.c
*** file1.c 2016-12-29 11:45:36.587010816 +0530
--- file2.c 2016-12-29 11:46:39.823013274 +0530
***************
*** 2,8 ****
void compare(float x, float y)
{
! if(x == y) // incorrect way
{
printf("\n EQUAL \n");
}
--- 2,8 ----
void compare(float x, float y)
{
! if(x == y)
{
printf("\n EQUAL \n");
}
Quindi, come puoi vedere, con -p , diff ti dà uno sguardo più dettagliato su dove si trova la modifica, indicando le diverse righe usando un punto esclamativo (!).
7. Confronta ricorsivamente le sottodirectory
Il comando diff ti consente anche di confrontare ricorsivamente le sottodirectory, ma non è il suo comportamento predefinito. Quello che voglio dire è, se prendi il seguente caso:
$ diff diff-files/ second-diff-files/
diff diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello
Il comando diff confronta solo i file nelle directory di livello superiore, ma se usi l'opzione della riga di comando -r (che è per diff ricorsivo), vedrai che vengono confrontati anche i file presenti nelle sottodirectory:
$ diff -r diff-files/ second-diff-files/
diff -r diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff -r diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello
diff -r diff-files/more-diff-files/file1 second-diff-files/more-diff-files/file1
1c1
< Hi
---
> i
diff -r diff-files/more-diff-files/file2 second-diff-files/more-diff-files/file2
2c2
< Hello
---
> ello
8. Tratta i file assenti come vuoti
Il comando diff fornisce anche un'opzione mediante la quale è possibile indirizzare lo strumento a trattare i file assenti come vuoti. Ad esempio, se confronti file1 con file3 (che non esiste), il comportamento predefinito di diff è produrre un errore:
$ diff file1 file3
diff: file3: No such file or directory
Questo non è sbagliato di per sé; in effetti questo ha perfettamente senso. Ma potrebbero esserci casi in cui non vorresti che il comando diff generi un errore per tali situazioni (pur essendo parte di uno script bash, potrebbe essere?), quindi per quegli scenari, puoi usare l'opzione della riga di comando -N che obbliga il comando a trattare i file assenti come vuoti e continua con il confronto.
$ diff -N file1 file3
1,5d0
< Hi
<
< Helllo
<
< Bye
Conclusione
Se esamini correttamente entrambe le parti di questa serie di tutorial e fai pratica con tutti gli esempi contenuti negli articoli, non sarà esagerato dire che finirai per avere una buona padronanza dello strumento. Ovviamente, non abbiamo potuto discutere tutto ciò che riguarda le differenze in questa serie, ma ti assicuriamo che molte delle caratteristiche/funzionalità importanti sono state trattate.
Per coloro che desiderano saperne di più sull'utilità, la pagina man è sempre a tua disposizione. E per non parlare del fatto che dovresti continuare a utilizzare lo strumento frequentemente con diversi set di file in modo da simulare diversi casi d'uso.