Compara dos archivos línea por línea y genera la diferencia en otro archivo

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.

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).

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.

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”.

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) 

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 

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 

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.

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 blog que escribí sobre transmisiones difusas en la terminal, que presenta sd.

Use la utilidad Diff y extraiga solo las líneas que comienzan con

 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 .