El resultado de diff dos archivos con líneas cambiadas dice que falta la misma línea dos veces

28

Estoy tratando de entender el comando linux diff en dos archivos cuyas líneas son solo permutación entre sí pero no pueden asimilar el resultado que genera. Considere los tres comandos a continuación:

[myPrompt]$ cat file1
apples
oranges
[myPrompt]$ cat file2 
oranges
apples
[myPrompt]$ diff file1 file2
1d0
< apples
2a2
> apples

¿Alguien puede explicar el resultado críptico anterior de diff.

  1. ¿Por qué no hay mención alguna de "naranjas" en la salida?
  2. ¿Qué significa 1d0y qué 2a2significa?

Entiendo por esta respuesta que:

"<" significa que falta la línea en el archivo2 y ">" significa que falta la línea en el archivo1

PERO eso no explica por qué faltan naranjas en la salida.

Friki
fuente
12
Debido a que orangeses la parte común más grande entre los dos archivos, lo que obtienes es la forma más corta de expresar las diferencias entre los dos.
Stéphane Chazelas
10
Y si desea una salida más legible, simplemente use diff -u file1 file2en su lugar. Eso se llama formato "diff unificado". El formato diff original estaba destinado a ser muy compacto, pero los diff unificados están destinados a ser mucho más legibles.
godlygeek
44
@godlygeek Ordiff -y file1 file2
user80551

Respuestas:

27

Para comprender el informe, recuerde que diffes prescriptivo y describe los cambios que se deben realizar en el primer archivo ( file1) para que sea el mismo que el segundo archivo ( file2).

Específicamente, el din 1d0significa eliminar y el ain 2a2significa agregar .

Así:

  • 1d0significa que la línea 1 debe eliminarse en file1( apples). 0en 1d0significa que la línea 0 es donde habrían aparecido en el segundo archivo ( file2) si no se hubieran eliminado. Eso significa que cuando se cambia file2a file1(hacia atrás), agregue la línea 1 file1después de la línea 0 de file2.
  • 2a2significa agregar la segunda línea ( oranges) file2a la ahora segunda línea de file1(después de eliminar la primera línea file1, orangescambiar a la línea 1)
caos
fuente
lo que es 0en 1d0?
Geek
@Geek ve mi edición
caos
1
@Geek Pero ten cuidado, eso puede hacer nudos en el cerebro =)
caos
eso, de hecho, comenzó a hacer nudos :-)
Geek
13

Considere estos archivos:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

Cómo difffunciona, dado que está basado en pedidos:

  1. difflee el primer bloque de líneas de file1y file2, e intenta encontrar líneas iguales:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. Ahora omitirá todas las líneas que son iguales en ambos archivos, que es solo orangesen este caso:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. Ahora encuentre otro conjunto de líneas similares e imprima las diferencias:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. Salta las líneas similares

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. Encuentre líneas idénticas, si es posible, e imprima diferencias:

    line_file1    file1    line_file2    file2        differences on left (<) or right side (>)
             1    apples                              <apples 
             2    pears                               <pears 
             3    oranges           1    oranges
                                    2    apples       >apples
             4    peaches           3    peaches
                                    4    ananas       >ananas
                                    5    banana       >banana
             -----------------------------------------------
    

Ahora si lo hago diff file1 file2:

# diff file1 file2
1,2d0
< apples
< pears
3a2
> apples
4a4,5
> ananas
> banana

Ahora es simple explicar lo que diffsignifica la salida:

Para hacer file1igual a file2:

  • 1,2d0: Eliminar ( d) líneas 1-2de file1y modificar la línea 0en file2consecuencia
  • 3a2: Añadir ( a) a la línea 3de file1línea 2defile2
  • 4a4,5: Añadir a la línea 4de file1líneas 4-5defile2

diffse compara file1con file2línea por línea y resuelve diferencias en la memoria temporal. Después de hacer file1 igual a file2 hasta la primera aparición de una línea en file1, que también ocurre en file2, todas las líneas que son iguales hasta una diferencia no se mencionan, a menudo se indican como ---. En este caso solo hay una línea similar, que es oranges. Tenga en cuenta que dije file1igual a file2, por lo que file1se ve en relación con file2y no al revés.

La salida está en relación con el primer archivo dado, en este caso file1.

polimero
fuente
2
No me gusta la explicación inicial: también applesocurre en ambos archivos.
O Mapper
1
@ORMapper Cambié la explicación. ¿Suena más claro / mejor ahora :)?
polym
No del todo, por ahora escribiste "solo hay una línea similar, que es oranges". Incorrecto: en realidad hay dos líneas, que no solo son similares , sino absolutamente idénticas . Uno de ellos lee oranges, el otro lee apples. Además, su explicación (puramente basada en el orden) está en contradicción con el comentario de Stéphane sobre la pregunta (basada en la longitud): ¿quién tiene razón?
O Mapper
@ORMapper Olvidó "En este caso" y las líneas anteriores. Quise decir que en este paso solo hay una línea similar. Solo agregaré un ejemplo a mi respuesta para que se pueda entender mejor.
polym
1
@ORMapper ¿También puede darme un ejemplo que muestre que la respuesta basada en la longitud es correcta?
polym
8

Allí están:

$ diff file1 file2
1d0
< apples
2a2
> apples
$ diff file2 file1
1d0
< oranges
2a2
> oranges
usuario78677
fuente
8

El formato de salida estándar (antiguo) mostrará la diferencia entre los archivos sin texto circundante con áreas donde los archivos difieren.

Por ejemplo: 1d0 <(eliminar) significa que las manzanas deben eliminarse de la primera línea de file1, y 2a2 >(agregar) significa que las manzanas deben agregarse en file2la segunda línea, por lo que ambos archivos pueden coincidir.

La documentación disponible en info diffexplica más aún más:

Mostrando diferencias sin contexto

El diffformato de salida "normal" muestra cada trozo de diferencias sin ningún contexto circundante. A veces, dicha salida es la forma más clara de ver cómo han cambiado las líneas, sin el desorden de las líneas cercanas sin cambios (aunque puede obtener resultados similares con el contexto o formatos unificados utilizando 0 líneas de contexto). Sin embargo, este formato ya no se usa ampliamente para enviar parches; Para ello, el formato de contexto y el formato unificado son superiores. El formato normal es el predeterminado para la compatibilidad con versiones anteriores diffy el estándar POSIX. Use la --normalopción para seleccionar este formato de salida explícitamente.

Descripción detallada del formato normal

El formato de salida normal consta de uno o más trozos de diferencias; cada trozo muestra un área donde los archivos difieren. Los trozos de formato normal se ven así:

 CHANGE-COMMAND
 < FROM-FILE-LINE
 < FROM-FILE-LINE...
 ---
 > TO-FILE-LINE
 > TO-FILE-LINE...

Hay tres tipos de comandos de cambio. Cada uno consta de un número de línea o un rango de líneas separadas por comas en el primer archivo, un solo carácter que indica el tipo de cambio a realizar y un número de línea o un rango de líneas separadas por comas en el segundo archivo. Todos los números de línea son los números de línea originales en cada archivo. Los tipos de comandos de cambio son:

LaR Agregue las líneas en el rango R del segundo archivo después de la línea L del primer archivo. Por ejemplo, 8a12,15significa agregar las líneas 12-15 del archivo 2 después de la línea 8 del archivo 1; o, si cambia el archivo 2 en el archivo 1, elimine las líneas 12-15 del archivo 2.

FcT Reemplace las líneas en el rango F del primer archivo con líneas en el rango T del segundo archivo. Esto es como una combinación de agregar y eliminar, pero más compacta. Por ejemplo, 5,7c8,10significa cambiar las líneas 5-7 del archivo 1 para leer como líneas 8-10 del archivo 2; o, si cambia el archivo 2 en el archivo 1, cambie las líneas 8-10 del archivo 2 para leer como líneas 5-7 del archivo 1.

RdL Elimine las líneas en el rango R del primer archivo; la línea L es donde habrían aparecido en el segundo archivo si no se hubieran eliminado. Por ejemplo, 5,7d3significa eliminar las líneas 5-7 del archivo 1; o, si cambia el archivo 2 al archivo 1, agregue las líneas 5-7 del archivo 1 después de la línea 3 del archivo 2.

Ver también:


Entonces, para ver las naranjas, tendrías que diferenciarlas una al lado de la otra o usando un contexto unificado.

Por ejemplo:

$ diff -y file1 file2
apples                                <
oranges                             oranges
                                  > apples

$ diff -u file1 file2
@@ -1,2 +1,2 @@
-apples
 oranges
+apples
kenorb
fuente