El comando diff compara las diferencias entre ficheros línea a línea. Es un comando muy útil cuando queremos comprobar las diferencias entre archivos, probablemente entre archivos de log o entre archivos de configuración.


 
En este artículo:
 



 

 

La sintaxis simple del comando diff es:

1
diff fichero1 fichero2

 

De esta forma comparará las diferencias entre las lineas de estos dos ficheros, sin opciones especiales.

El comando diff mostrará las líneas que se tienen que cambiar para que los dos archivos coincidan.

 

El resultado es el siguiente:

  • los números de línea correspondientes al primer fichero
    • una coma entre números, para indicar un rango de líneas.
  • Una letra [ «a» (add)  para añadir, «c» (change) para cambiar, y «d» (delete) para borrar] para separar las líneas del primer fichero y del segundo.
  • los números de línea correspondientes al segundo fichero
  • Símbolos especiales en los cambios a realizar:
    • el símbolo < son líneas del primer fichero
    • el símbolo > son líneas del segundo fichero

 

 

Ejemplo 1 del comando diff

 

Tenemos el fichero «resolv.conf«, cuyo contenido es:

1
2
3
4
# Generated by NetworkManager
search midominio
nameserver 192.168.8.1
nameserver 8.8.8.8

 

y el archivo «resolv.conf.bak«, cuyo contenido es:

1
2
3
4
# Generated by NetworkManager
search midominio
nameserver 192.168.8.1
nameserver 4.4.4.4

 

Cómo vemos, lo único que cambia es la última línea, la línea número 4.

Y al hacer diff de los dos ficheros, el resultado es:

1
2
3
4
5
# diff resolv.conf resolv.conf.bak
4c4
< nameserver 8.8.8.8
---
> nameserver 4.4.4.4

 

Significado del resultado mostrado por diff

 
O sea, diff  nos dice:

  • En el primer fichero tienes que cambiar la linea 4 ( < nameserver 8.8.8.8 )
  • para que ambos ficheros sean iguales en la línea 4 del segundo fichero.
    • [ y muestra el contenido de la linea 4 del segundo fichero ( > nameserver 4.4.4.4 ) ]

 

comando diff - ejemplo 1

 

 

Ejemplo 2 del comando diff

 
Añadimos un espacio en el primer archivo, quedando así:
 

1
2
3
4
5
# Generated by NetworkManager
search midominio
nameserver 192.168.8.1
 
nameserver 8.8.8.8

 

Y el segundo queda así:

1
2
3
4
# Generated by NetworkManager
search midominio
nameserver 192.168.8.1
nameserver 4.4.4.4

 

Y al hacer diff, el resultado es:

1
2
3
4
5
6
# diff resolv.conf resolv.conf.bak
4,5c4
<
< nameserver 8.8.8.8
---
> nameserver 4.4.4.4

 

Significado del resultado mostrado por diff

 

  • de la línea 4 a la 5 del primer archivo
  • tienes que cambiar esto para que los dos archivos sean iguales a partir de la linea 4:
    • del archivo 1 :
1
2
<
< nameserver 8.8.8.8

 

    • del archivo 2:
1
> nameserver 4.4.4.4

 

 

comando diff - ejemplo 2
 

 

Ejemplo 3 del comando diff

 
De nuevo, tenemos estos dos ficheros:

1
2
3
4
5
6
7
8
# Generated by NetworkManager
search midominio
linea3
linea4
nameserver 192.168.8.1
linea6
nameserver 4.4.4.4
linea8
1
2
3
4
# Generated by NetworkManager
search midominio
nameserver 192.168.8.1
nameserver 4.4.4.4

 

Y el resultado de diff es:

1
2
3
4
5
6
7
8
9
10
diff resolv.conf resolv.conf.bak
3,4d2
< linea3
< linea4
6,8c4
< linea6
< nameserver 8.8.8.8
< linea8
---
> nameserver 4.4.4.4

 

Significado del resultado mostrado por diff

 

1
diff resolv.conf resolv.conf.bak

 

1
2
3
3,4d2
< linea3
< linea4

 

De la línea 3 a la 4 del primer fichero (3,4), tienes que BORRAR (d),

para que en la línea 2 del segundo fichero, ambos sean IGUALES.

 

Y esto, perteneciente al primer fichero (por el símbolo < ) es lo que hay que BORRAR:

1
2
< linea3
< linea4

 

Seguimos:
 

1
2
6d3
< linea6


 

De la línea 6 a la 8 del primer fichero (6,8), tienes que CAMBIAR (c), para que en la línea 4 del segundo fichero, ambos sean IGUALES.

 

Y esto, correspondiente al primer fichero (por el símbolo < ), es lo que tienes que CAMBIAR

1
2
3
4
< linea6
< nameserver 8.8.8.8
< linea8
---

 

Y esto, correspondiente al segundo fichero (por el símbolo > ), es lo que tienes que CAMBIAR

1
> nameserver 4.4.4.4

comando diff - ejemplo 3

 

 

Ejemplo 4 – diff recursivo (compara subdirectorios que encuentra)

 
El comando diff también puede hacer comparaciones recursivas dentro de directorios y subdirectorios.
 

Con el parámetro -rq, realiza comparación recursiva.

-r :recursivo

-q: muestra por pantalla solo cuando hay diferencias


 

comando diff recursivo
 

 

Ejemplo 5 – diff en modo contextual (-c)

 
El modo contextual del comando diff está diseñado para ver de un modo más visual las diferencias en las líneas de los ficheros comparados.

De nuevo, lo veremos mejor con un ejemplo. Tenemos estos dos ficheros:

1
2
3
4
[root@centos]# cat resolv.conf
# Generated by NetworkManager
search Midominio
nameserver 192.168.8.1

 

1
2
3
4
5
[root@centos]# cat resolv.conf.bak
# Generated by NetworkManager
search Midominio
nameserver 192.168.8.1
nameserver 8.8.8.8

 

Podemos ver que son iguales a excepción de la última línea del segundo fichero, que es una línea nueva que no encontramos en el primer fichero.

Y al ejecutar diff, obtenemos:

1
2
3
4
5
6
7
8
9
10
[root@centos]# diff -c resolv.conf resolv.conf.bak
*** resolv.conf 2020-02-24 02:55:15.888339020 +0100
--- resolv.conf.bak 2020-02-24 02:55:58.094236116 +0100
***************
*** 1,3 ****
--- 1,4 ----
# Generated by NetworkManager
search Midominio
nameserver 192.168.8.1
+ nameserver 8.8.8.8

 

Significado del resultado mostrado por diff contextual

 

Primero muestra info de los ficheros, como su nombre y la fecha de modificación.

El primer fichero tiene delante ***

el segundo fichero tiene delante —

Luego está el separador ***************

Luego muestra tres asteriscos, seguidos de un rango de líneas (en este caso de la línea 1 a la 3), y otros cuatro asteriscos.

Luego muestra el contenido de esas líneas. Si la línea no cambia, tiene 2 espacios como prefijo.

Sin embargo, si la línea ha cambiado, tiene como prefijo un carácter indicativo y dos espacios.


comando diff contextual
 

Los significados de los caracteres son los siguientes:

!    Indica que esta linea es parte de un grupo de una o más lineas que necesita cambiar.

+ Indica una línea en el segundo archivo que debe agregarse al primer archivo.

– indica una línea en el primer archivo que debe eliminarse.


 

Después de las líneas del primer archivo, hay tres guiones, luego un rango de linea, y luego cuatro guiones. Esto indica el rango de línea en el segundo archivo que se sincronizará con nuestros cambios en el primer archivo.

 

 

Ejemplo 6 – diff en modo unificado (-u)

 
El modo unificado es muy parecido al contextual, pero no muestra info redundante.

Utilizando los mismos ficheros que en el ejemplo anterior (el de diff contextual), podemos ver que las diferencias están «unificadas».

El resultado del diff unificado muestra:

1
2
3
4
5
6
7
8
[root@centos]# diff -u resolv.conf resolv.conf.bak
--- resolv.conf 2020-02-24 02:55:15.888339020 +0100
+++ resolv.conf.bak 2020-02-24 02:55:58.094236116 +0100
@@ -1,3 +1,4 @@
# Generated by NetworkManager
search Midominio
nameserver 192.168.8.1
+nameserver 8.8.8.8

 

Y el resultado de diff significa:

De este número de líneas (de la 1 a la 3) del fichero 1 , a este número de líneas del fichero 2 (de la 1 a la 4).

Y luego muestra las líneas de los ficheros que tienen diferencias:

  • Las líneas que comienzan con dos espacios son líneas de contexto, líneas que son iguales.
  • Las líneas que comienzan con el símbolo menos ( – ) son líneas que se eliminan del primer fichero.
  • Las líneas que comienzan con el símbolo más ( + ) son líneas que se agregan desde el primer fichero.

 

comando diff unificado
 

 

Opciones útiles y parámetros del comando diff más utilizados

 

–normal    : la opción por defecto de diff, arroja los resultados mostrándolos de forma «normal».

-i  : Con este parámetro, diff NO examina las diferencias entre mayúsculas y minúsculas, o sea, diff actúa como Case insensitive (NO afectado por las diferencias entre mayúsculas y minúsculas).  (por defecto, diff SÍ que examina las diferencias entre mayúsculas y minúsculas).

-u : Muestra el formato unificado.

-c : Muestra el modo contextual

-b : Ignora cambios que solo cambie la cantidad de espacios en blanco.

-w :  ignora los espacios en blanco por completo.

-B : ignora las líneas en blanco al calcular las diferencias.

-y : muestra la salida en dos columnas

-r :recursivo

-q: muestra por pantalla solo cuando hay diferencias