shell - texto - Compara dos archivos línea por línea y genera la diferencia en otro archivo
programa para comparar archivos xml (9)
Quiero comparar el archivo1 con el archivo2 y generar un archivo3 que contenga las líneas en el archivo1 que no están presentes en el archivo2.
A veces, diff
es la utilidad que necesita, pero a veces join
es más apropiado. Los archivos deben ser ordenados previamente o, si está utilizando un shell que admite la sustitución de procesos como bash, ksh o zsh, puede hacer el orden sobre la marcha.
join -v 1 <(sort file1) <(sort file2)
Considera esto:
archivo a.txt:
abcd
efgh
archivo b.txt:
abcd
Usted puede encontrar la diferencia con:
diff -a --suppress-common-lines -y a.txt b.txt
El resultado será:
efgh
Puede redirigir el resultado en un archivo de salida (c.txt) usando:
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
Esto responderá a tu pregunta:
"... que contiene las líneas del archivo1 que no están en el archivo2".
La utilidad diff
Unix está diseñada para exactamente este propósito.
$ diff -u file1 file2 > file3
Consulte el manual e Internet para conocer las opciones, los diferentes formatos de salida, etc.
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 proceso de sustitución y admite transmisiones infinitas, así:
cat file1 | sd ''cat file2'' > file3
Probablemente no sea tan beneficioso en este ejemplo, pero aún así lo considere; en algunos casos, no podrá usar comm
ni grep -F
ni diff
.
Aquí hay una entrada de blogpost que escribí sobre transmisiones difusas en la terminal, que presenta sd.
Tratar
sdiff file1 file2
Por lo general, 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
Use la utilidad Diff y extraiga solo las líneas que comienzan con <en la salida
Ya hay muchas respuestas, pero ninguna de ellas es 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 sean ordenados o pre-ordenados, 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 (sin caracteres adicionales, sin reordenar) es una combinación de diff
, grep
y awk
(o similar).
Si las líneas no contienen ningún "<", un trazo corto puede ser:
diff urls.txt* | grep "<" | sed ''s/< //g''
pero eso eliminará cada instancia de "<" (menor que, espacio) de las líneas, lo que no siempre es correcto (por ejemplo, el 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}''
Este unidireccional diferencia ambos archivos, luego filtra el resultado del estilo ed de diff y luego elimina el "<" final que agrega diff. Esto funciona incluso si las líneas contienen algunos "<" ellos mismos.
diff (1) no es la respuesta, pero comm (1) es.
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
Asi que
comm -2 -3 file1 file2 > file3
Los archivos de entrada deben estar ordenados. Si no lo son, ordénelos primero. Esto se puede hacer con un archivo temporal, o ...
comm -2 -3 <(sort file1) <(sort file2) > file3
siempre que su shell soporte la sustitución de procesos (bash does).
diff a1.txt a2.txt | grep ''> '' | sed ''s/> //'' > a3.txt
Intenté casi todas las respuestas en este hilo, pero ninguna fue completa. Después de algunos senderos arriba uno funcionó para mí. diff te dará diferencia pero con algunas charas especiales no deseadas. donde las líneas de diferencias reales comienzan con ''>''. así que el siguiente paso es grep las líneas comienzan con ''>'' y luego se eliminan con sed .