¿Cómo comparar dos archivos diferentes línea por línea en unix?


13

Archivo1:

123
234
345
456

Archivo2:

123
234
343
758

Salida esperada: File3:

TRUE
TRUE
FALSE
FALSE

entonces el código debe comparar dos archivos e imprimir 'VERDADERO' si coincide, de lo contrario debería imprimir 'FALSO' en el nuevo archivo. ¿Alguien podría proporcionar la solución para esto?


10
¿Qué sucede si los dos archivos tienen una longitud desigual? ¿Con qué parte de la solución de este problema está teniendo problemas?
Kusalananda

99
Es posible que desee echar un vistazo diff.
Panki

2
Otro comando útil en estas situaciones es comm. Facilita la enumeración de líneas que ambos archivos tienen en común o son exclusivas de uno u otro.
Giacomo Alzetta

1
@GiacomoAlzetta Lo que pasa commes que requiere una entrada ordenada. Además del hecho de que el ejemplo en la pregunta tiene una entrada ordenada, la pregunta nunca afirma que estos son los datos reales que se están utilizando y nunca dice nada sobre el orden de los datos.
Kusalananda

2
El nltruco de αғsнιη es útil commpara imponer la ordenación en los archivos.
Glenn Jackman

Respuestas:


56

Use el diffcomando de la siguiente manera, en bashcualquier otro shell que admita <(...) sustituciones de proceso o puede emularlo como se muestra aquí :

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

La salida sería:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, imprime FALSEsi las líneas eran diferentes y con la --old-line-format=''opción de deshabilitar la salida si la línea era diferente para el archivo1, que se conoce como comando de archivo antiguo a dif FALSE.

--unchanged-line-format='TRUE'$'\n', imprima TRUEsi las líneas fueran iguales. La $'\n'sintaxis de escape de estilo C se utiliza para imprimir una nueva línea después de cada salida de línea.


24

Suponiendo que los archivos no contienen caracteres de tabulación:

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

Esto se usa pastepara crear dos columnas delimitadas por tabuladores, con el contenido de los dos archivos en cualquier columna. El awkcomando compara las dos columnas en cada línea e imprime TRUEsi las columnas son iguales y, de lo contrario, imprime FALSE.


10

Suponiendo que ambos archivos tengan el mismo número de líneas:

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

Eso es hacer una comparación numérica si las cadenas para comparar son números y léxico de lo contrario. Por ejemplo, 100y 1.0e2se consideraría idéntico. Cambie a f2"" == $0para forzar una comparación léxica en cualquier caso.

Dependiendo de la awkimplementación, la comparación léxica se realizará como si se usara memcmp()(comparación byte a byte) o como si se usara strcoll()(si las dos cadenas se ordenan de la misma manera en el orden de clasificación de la configuración regional). Eso puede marcar la diferencia en algunas configuraciones regionales donde el orden no está definido correctamente para algunos caracteres, no en todos los dígitos decimales como en su muestra.


7

Python 3

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

Salida:

True
True
False
False

Si lo necesita TRUEy FALSEen mayúsculas, reemplace la línea de impresión con una de estas:

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
En Python 2, haga import itertoolsprimero y luego use en itertools.iziplugar de zip. De lo contrario, leerá ambos archivos en la memoria, posiblemente utilizando demasiada memoria.
pts

4

En bash, leyendo de cada archivo en un whilebucle, comparando las líneas de lectura e imprimiendo TRUEo FALSEapropiadamente:

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

Las dos llamadas a readlecturas del descriptor de archivo 3 y 4 respectivamente. Los archivos se redirigen a estos con dos redirecciones de entrada al bucle.


0
Tried with awk command and it worked fine


awk 'NR==FNR{a[$1];next}{if ($1 in a){print "TRUE"} else{print "False"}}' file1 file2

salida

TRUE
TRUE
False
False
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.