¿Cómo puedo obtener diff para mostrar solo líneas agregadas y eliminadas? Si diff no puede hacerlo, ¿qué herramienta puede?
diff A B | grep '^[<>]'
comm
.
¿Cómo puedo obtener diff para mostrar solo líneas agregadas y eliminadas? Si diff no puede hacerlo, ¿qué herramienta puede?
diff A B | grep '^[<>]'
comm
.
Respuestas:
Otra forma de verlo:
Mostrar líneas que solo existen en el archivo a: (es decir, lo que se eliminó de a)
comm -23 a b
Mostrar líneas que solo existen en el archivo b: (es decir, lo que se agregó a b)
comm -13 a b
Mostrar líneas que solo existen en un archivo u otro: (pero no en ambos)
comm -3 a b | sed 's/^\t//'
(Advertencia: si el archivo a
tiene líneas que comienzan con TAB, se eliminará de la salida (la primera TAB).
NOTA: Ambos archivos deben ser ordenados para comm
trabajar correctamente. Si aún no están ordenados, debe ordenarlos:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Si los archivos son extremadamente largos, esto puede ser una gran carga ya que requiere una copia adicional y, por lo tanto, el doble de espacio en disco.
comm -12 <(sort a) <(sort b)
comm
podría hacer lo que quieras. Desde su página de manual:
DESCRIPCIÓN
Compare los archivos ordenados FILE1 y FILE2 línea por línea.
Sin opciones, produce una salida de tres columnas. La columna uno contiene líneas exclusivas de FILE1, la columna dos contiene líneas exclusivas de FILE2 y la columna tres contiene líneas comunes a ambos archivos.
Estas columnas se pueden suprimir con -1
, -2
y -3
respectivamente.
Ejemplo:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
Y si solo quieres las líneas únicas y no te importa en qué archivo están:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Como dice la página del manual, los archivos deben ordenarse de antemano.
Para mostrar adiciones y eliminaciones sin contexto, números de línea, +, -, <,>! etc, puedes usar diff así:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Por ejemplo, dados dos archivos:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
El siguiente comando mostrará líneas eliminadas de ao agregadas a b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
salida:
B-ONLY
A-ONLY
Este comando ligeramente diferente mostrará líneas eliminadas de a.txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
salida:
A-ONLY
Finalmente, este comando mostrará líneas agregadas a a.txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
salida
B-ONLY
Eso es lo que hace diff por defecto ... ¿Quizás necesite agregar algunas banderas para ignorar los espacios en blanco?
diff -b -B
debe ignorar líneas en blanco y diferentes números de espacios.
No, en diff
realidad no muestra las diferencias entre dos archivos en la forma en que uno podría pensar. Produce una secuencia de comandos de edición para una herramienta como patch
para cambiar un archivo a otro.
La dificultad para cualquier intento de hacer lo que está buscando es cómo definir qué constituye una línea que ha cambiado frente a una eliminada seguida de una añadida. También qué hacer cuando se agregan, eliminan y cambian líneas adyacentes entre sí.
diff
fuentes, pero parece recordar todo tipo de giros para hacer un seguimiento de dónde coinciden dos archivos para mantenerse sincronizados y creo que hay un umbral para renunciar en función de qué tan separados están las líneas son Pero no recuerdo ninguna coincidencia intralínea, excepto (opcionalmente) el espacio en blanco colapsado o el caso ignorado. O (tal vez) palabras a ese efecto. En cualquier caso, se trata de todo patch
y "vgrep" simplemente aparece para el viaje. Tal vez. El martes.
Las herramientas de comparación visual ajustan dos archivos juntos para que un segmento con el mismo número de líneas pero contenido diferente se considere un segmento cambiado. Las líneas completamente nuevas entre segmentos coincidentes se consideran segmentos agregados.
Así es también como funciona la herramienta de línea de comandos sdiff , que muestra una comparación lado a lado de dos archivos en un terminal. Las líneas modificadas están separadas por | personaje. Si solo existe una línea en el archivo A, <se utiliza como carácter separador. Si existe una línea solo en el archivo B,> se usa como separador. Si no tiene caracteres <y> en los archivos, puede usar esto para mostrar solo las líneas agregadas:
sdiff A B | grep '[<>]'
Gracias senarvi, su solución (no votada) en realidad me dio EXACTAMENTE lo que quería después de buscar años en una tonelada de páginas.
Usando su respuesta, esto es lo que se me ocurrió para cambiar / agregar / eliminar la lista de cosas. El ejemplo utiliza 2 versiones del archivo / etc / passwd e imprime el nombre de usuario para los registros relevantes.
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
Encuentro esta forma particular a menudo útil:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Ejemplo:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Salida:
-b
-c
+B
+C
-e
-f
+E
+F
Por lo tanto, muestra líneas antiguas -
seguidas inmediatamente por la nueva línea correspondiente con +
.
Si tuvimos una eliminación de C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
se parece a esto:
-b
+B
+C
-e
-f
+E
+F
El formato está documentado en man diff
:
--line-format=LFMT
format all input lines with LFMT`
y:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
y:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Pregunta relacionada: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
Probado en Ubuntu 18.04.
Archivo1:
text670_1
text067_1
text067_2
Archivo2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Utilizar:
diff -y file1 file2
Esto muestra dos columnas para archivos de referencias.
Salida:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1