Probé con diff pero genera algunos números y otros símbolos delante de diferentes líneas que me dificulta comparar archivos.
dom
Respuestas:
216
diff (1) no es la respuesta, pero comm (1) sí.
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
Entonces
comm -2-3 file1 file2 > file3
Los archivos de entrada deben estar ordenados. Si no es así, ordénelos primero. Esto se puede hacer con un archivo temporal o ...
comm -2-3<(sort file1)<(sort file2)> file3
siempre que su shell admita la sustitución de procesos (bash lo hace).
Recuerde que dos archivos deben estar ordenados y son únicos
andy
6
Puede agrupar las opciones:comm -23
Paolo M
¿Qué significa "ordenado"? ¿Que las líneas tienen el mismo orden? Entonces probablemente esté bien para la mayoría de los casos de uso, como por ejemplo, verificar qué líneas se han agregado comparándolas con una versión anterior respaldada. Si las líneas recién agregadas no pueden estar entre las líneas existentes, eso es un problema mayor.
Egor Hans
@EgorHans: si el archivo tiene, por ejemplo, líneas que contienen números enteros como "3 \ n1 \ n3 \ n2 \ n", las líneas deben reordenarse primero en orden ascendente o descendente, por ejemplo, "\ 1 \ n2 \ n3 \ n3 \ n" con duplicados adyacente. Eso está "ordenado" y ambos archivos se deben ordenar de manera similar. Cuando el archivo más nuevo tiene nuevas líneas, no importa si están "entre líneas existentes" porque después de la clasificación no lo están, están en orden.
Sorigal
48
La utilidad Unix diffestá diseñada exactamente para este propósito.
$ diff -u file1 file2 > file3
Consulte el manual e Internet para conocer las opciones, los diferentes formatos de salida, etc.
Eso no hace el trabajo solicitado; inserta un montón de caracteres adicionales, incluso con el uso de interruptores de línea de comando sugeridos en otras respuestas.
xenocyon
20
Considere esto:
archivo a.txt:
abcd
efgh
archivo b.txt:
abcd
Puedes encontrar la diferencia con:
diff -a --suppress-common-lines -y a.txt b.txt
La salida será:
efgh
Puede redirigir la salida en un archivo de salida (c.txt) usando:
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
Esto responderá a su pregunta:
"... que contiene las líneas en el archivo1 que no están presentes en el archivo2".
Hay dos limitaciones para esta respuesta: (1) solo funciona para líneas cortas (menos de 80 caracteres por defecto, aunque esto se puede modificar) y, lo que es más importante, (2) agrega un "<" al final de cada línea que debe eliminarse con otro programa (por ejemplo, awk, sed).
sergut
En muchos casos, también querrá usar -d, lo que hará difftodo lo posible para encontrar la diferencia más pequeña posible. -i, -E, -w, -BY --suppress-blank-emptytambién puede ser útil en ocasiones, aunque no siempre. Si no sabe qué se ajusta a su caso de uso, intente diff --helpprimero (que generalmente es una buena idea cuando no sabe lo que puede hacer un comando).
Egor Hans
Además, al usar --line-format =% L, evita que diff genere caracteres adicionales (al menos, la ayuda dice que funciona así, pero está a punto de probarlo).
A veces diffes la utilidad que necesita, pero a veces joines más adecuada. Los archivos deben ordenarse previamente o, si está utilizando un shell que admita la sustitución de procesos como bash, ksh o zsh, puede ordenarlos sobre la marcha.
¡Deberías conseguir una medalla por esto! Era exactamente lo que estaba buscando las últimas 2 horas
Zatarra
7
Tratar
sdiff file1 file2
Normalmente funciona mucho mejor en la mayoría de los casos para mí. Es posible que desee ordenar los archivos antes, si el orden de las líneas no es importante (por ejemplo, algunos archivos de configuración de texto).
¡Buena utilidad! Me encanta cómo marca las líneas diferenciadoras. Hace que sea mucho más fácil comparar configuraciones. Esto, junto con el tipo es un combo mortal (por ejemplo sdiff <(sort file1) <(sort file2))
jmagnusson
3
Si necesita resolver esto con coreutils, la respuesta aceptada es buena:
comm -23<(sort file1)<(sort file2)> file3
También puede usar sd (stream diff), que no requiere clasificación ni sustitución de procesos y admite flujos infinitos, así:
cat file1 | sd 'cat file2'> file3
Probablemente no sea un gran beneficio en este ejemplo, pero aún así considérelo; en algunos casos no podrás utilizar commni grep -Fni diff.
Aquí hay una entrada de blog que escribí sobre las diferentes transmisiones en la terminal, que presenta sd.
Muchas respuestas ya, pero ninguna de ellas perfecta en mi humilde opinión. La respuesta de Thanatos deja algunos caracteres adicionales por línea y la respuesta de Sorpigal requiere que los archivos se clasifiquen o preordenan, lo que puede no ser adecuado en todas las circunstancias.
Creo que la mejor manera de obtener las líneas que son diferentes y nada más (no hay caracteres adicionales, sin volver a realizar el pedido) es una combinación de diff, grepy awk(o similar).
Si las líneas no contienen ningún "<", una línea breve puede ser:
diff urls.txt*| grep "<"| sed 's/< //g'
pero eso eliminará todas las instancias de "<" (menos que, espacio) de las líneas, lo que no siempre está bien (por ejemplo, código fuente). La opción más segura es usar awk:
Esta línea única diferencia ambos archivos, luego filtra la salida de estilo ed de diff, luego elimina el "<" final que agrega diff. Esto funciona incluso si las líneas contienen algunos "<".
Probé casi todas las respuestas en este hilo, pero ninguna estaba completa. Después de algunos senderos arriba, uno funcionó para mí. diff le dará una diferencia pero con algunos charas especiales no deseados. donde las líneas de diferencia reales comienzan con '>'. así que el siguiente paso es que las líneas grep comiencen con '>' y luego las eliminen con sed .
Esta es una mala idea. También necesitaría modificar las líneas que comienzan con <. Verá esto si cambia el orden de los archivos de entrada. Incluso si hiciera esto, querría omitir grepusando más sed: `diff a1 a2 | sed '/> / s ///' `Esto todavía puede romper las líneas que contienen >o <en la situación correcta y todavía deja líneas adicionales que describen los números de línea. Si quería probar este enfoque de una mejor manera sería: diff -C0 a1 a2 | sed -ne '/^[+-] /s/^..//p'.
sorigal
0
Puede usar diffcon el siguiente formato de salida:
--old-line-format='', deshabilite la salida para file1 si la línea es diferente compare en file2. --unchanged-line-format='', deshabilite la salida si las líneas son las mismas.
Respuestas:
diff (1) no es la respuesta, pero comm (1) sí.
Entonces
Los archivos de entrada deben estar ordenados. Si no es así, ordénelos primero. Esto se puede hacer con un archivo temporal o ...
siempre que su shell admita la sustitución de procesos (bash lo hace).
fuente
comm -23
La utilidad Unix
diff
está diseñada exactamente para este propósito.Consulte el manual e Internet para conocer las opciones, los diferentes formatos de salida, etc.
fuente
Considere esto:
archivo a.txt:
archivo b.txt:
Puedes encontrar la diferencia con:
La salida será:
Puede redirigir la salida en un archivo de salida (c.txt) usando:
Esto responderá a su pregunta:
fuente
-d
, lo que harádiff
todo lo posible para encontrar la diferencia más pequeña posible.-i
,-E
,-w
,-B
Y--suppress-blank-empty
también puede ser útil en ocasiones, aunque no siempre. Si no sabe qué se ajusta a su caso de uso, intentediff --help
primero (que generalmente es una buena idea cuando no sabe lo que puede hacer un comando).A veces
diff
es la utilidad que necesita, pero a vecesjoin
es más adecuada. Los archivos deben ordenarse previamente o, si está utilizando un shell que admita la sustitución de procesos como bash, ksh o zsh, puede ordenarlos sobre la marcha.fuente
Tratar
Normalmente funciona mucho mejor en la mayoría de los casos para mí. Es posible que desee ordenar los archivos antes, si el orden de las líneas no es importante (por ejemplo, algunos archivos de configuración de texto).
Por ejemplo,
fuente
sdiff <(sort file1) <(sort file2)
)Si necesita resolver esto con coreutils, la respuesta aceptada es buena:
También puede usar sd (stream diff), que no requiere clasificación ni sustitución de procesos y admite flujos infinitos, así:
Probablemente no sea un gran beneficio en este ejemplo, pero aún así considérelo; en algunos casos no podrás utilizar
comm
nigrep -F
nidiff
.Aquí hay una entrada de blog que escribí sobre las diferentes transmisiones en la terminal, que presenta sd.
fuente
Sin embargo, ¿no hay
grep
solución?líneas que existen solo en file2:
líneas que existen solo en el archivo1:
líneas que existen en ambos archivos:
fuente
Muchas respuestas ya, pero ninguna de ellas perfecta en mi humilde opinión. La respuesta de Thanatos deja algunos caracteres adicionales por línea y la respuesta de Sorpigal requiere que los archivos se clasifiquen o preordenan, lo que puede no ser adecuado en todas las circunstancias.
Creo que la mejor manera de obtener las líneas que son diferentes y nada más (no hay caracteres adicionales, sin volver a realizar el pedido) es una combinación de
diff
,grep
yawk
(o similar).Si las líneas no contienen ningún "<", una línea breve puede ser:
pero eso eliminará todas las instancias de "<" (menos que, espacio) de las líneas, lo que no siempre está bien (por ejemplo, código fuente). La opción más segura es usar awk:
Esta línea única diferencia ambos archivos, luego filtra la salida de estilo ed de diff, luego elimina el "<" final que agrega diff. Esto funciona incluso si las líneas contienen algunos "<".
fuente
Me sorprende que nadie ha mencionado
diff -y
a producir una salida de lado a lado , por ejemplo:Y en
file3
(las diferentes líneas tienen un símbolo|
en el medio):fuente
Use la utilidad Diff y extraiga solo las líneas que comienzan con <en la salida
fuente
Probé casi todas las respuestas en este hilo, pero ninguna estaba completa. Después de algunos senderos arriba, uno funcionó para mí. diff le dará una diferencia pero con algunos charas especiales no deseados. donde las líneas de diferencia reales comienzan con '>'. así que el siguiente paso es que las líneas grep comiencen con '>' y luego las eliminen con sed .
fuente
<
. Verá esto si cambia el orden de los archivos de entrada. Incluso si hiciera esto, querría omitirgrep
usando más sed: `diff a1 a2 | sed '/> / s ///' `Esto todavía puede romper las líneas que contienen>
o<
en la situación correcta y todavía deja líneas adicionales que describen los números de línea. Si quería probar este enfoque de una mejor manera sería:diff -C0 a1 a2 | sed -ne '/^[+-] /s/^..//p'
.Puede usar
diff
con el siguiente formato de salida:--old-line-format=''
, deshabilite la salida para file1 si la línea es diferente compare en file2.--unchanged-line-format=''
, deshabilite la salida si las líneas son las mismas.fuente