Quiero comparar file1 con file2 y generar un file3 que contiene las líneas en file1 que no están presentes en file2.
Quiero comparar file1 con file2 y generar un file3 que contiene las líneas en file1 que no están presentes en file2.
Respuestas:
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).
comm -23
La utilidad Unix diff
está 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.
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".
-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, intente diff --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 veces join
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.
join -v 1 <(sort file1) <(sort file2)
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).
Por ejemplo,
sdiff -w 185 file1.cfg file2.cfg
sdiff <(sort file1) <(sort file2)
)
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 comm
ni grep -F
ni 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
, grep
y 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:
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
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 "<".
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
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 .
<
. Verá esto si cambia el orden de los archivos de entrada. Incluso si hiciera esto, querría omitir grep
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:
diff --old-line-format='' --unchanged-line-format='' file1 file2
--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.