Comparar dos archivos reportan la diferencia en Python

Tengo 2 archivos llamados “hosts” (en directorios diferentes)

Quiero compararlos usando python para ver si son IDENTICOS. Si no son idénticos, quiero imprimir la diferencia en la pantalla.

Hasta ahora he intentado esto

hosts0 = open(dst1 + "/hosts","r") hosts1 = open(dst2 + "/hosts","r") lines1 = hosts0.readlines() for i,lines2 in enumerate(hosts1): if lines2 != lines1[i]: print "line ", i, " in hosts1 is different \n" print lines2 else: print "same" 

Pero cuando corro esto, me sale

 File "./audit.py", line 34, in  if lines2 != lines1[i]: IndexError: list index out of range 

Lo que significa que uno de los hosts tiene más líneas que el otro. ¿Hay un método mejor para comparar 2 archivos y reportar la diferencia?

 import difflib lines1 = ''' dog cat bird buffalo gophers hound horse '''.strip().splitlines() lines2 = ''' cat dog bird buffalo gopher horse mouse '''.strip().splitlines() # Changes: # swapped positions of cat and dog # changed gophers to gopher # removed hound # added mouse for line in difflib.unified_diff(lines1, lines2, fromfile='file1', tofile='file2', lineterm=''): print line 

Salidas de lo siguiente:

 --- file1 +++ file2 @@ -1,7 +1,7 @@ +cat dog -cat bird buffalo -gophers -hound +gopher horse +mouse 

Esta diferencia le da contexto, líneas circundantes para ayudar a aclarar en qué se diferencia el archivo. Puedes ver “gato” aquí dos veces, porque se eliminó de debajo de “perro” y se agregó encima.

Puedes usar n = 0 para eliminar el contexto.

 for line in difflib.unified_diff(lines1, lines2, fromfile='file1', tofile='file2', lineterm='', n=0): print line 

Saliendo esto:

 --- file1 +++ file2 @@ -0,0 +1 @@ +cat @@ -2 +2,0 @@ -cat @@ -5,2 +5 @@ -gophers -hound +gopher @@ -7,0 +7 @@ +mouse 

Pero ahora está lleno de las líneas “@@” que le indican la posición en el archivo que ha cambiado. Vamos a eliminar las líneas adicionales para que sea más legible.

 for line in difflib.unified_diff(lines1, lines2, fromfile='file1', tofile='file2', lineterm='', n=0): for prefix in ('---', '+++', '@@'): if line.startswith(prefix): break else: print line 

Dándonos esta salida:

 +cat -cat -gophers -hound +gopher +mouse 

Ahora que quieres que haga? Si ignora todas las líneas eliminadas, entonces no verá que se eliminó “hound”. Si está contento simplemente mostrando las adiciones al archivo, entonces puede hacer esto:

 diff = difflib.unified_diff(lines1, lines2, fromfile='file1', tofile='file2', lineterm='', n=0) lines = list(diff)[2:] added = [line[1:] for line in lines if line[0] == '+'] removed = [line[1:] for line in lines if line[0] == '-'] print 'additions:' for line in added: print line print print 'additions, ignoring position' for line in added: if line not in removed: print line 

Salida:

 additions: cat gopher mouse additions, ignoring position: gopher mouse 

A estas alturas, es probable que sepa que existen varias formas de “imprimir las diferencias” de dos archivos, por lo que deberá ser muy específico si desea más ayuda.

La biblioteca difflib es útil para esto, y viene en la biblioteca estándar. Me gusta el formato diff unificado.

http://docs.python.org/2/library/difflib.html#difflib.unified_diff

 import difflib import sys with open('/tmp/hosts0', 'r') as hosts0: with open('/tmp/hosts1', 'r') as hosts1: diff = difflib.unified_diff( hosts0.readlines(), hosts1.readlines(), fromfile='hosts0', tofile='hosts1', ) for line in diff: sys.stdout.write(line) 

Salidas:

 --- hosts0 +++ hosts1 @@ -1,5 +1,4 @@ one two -dogs three 

Y aquí hay una versión poco fiable que ignora ciertas líneas. Puede que haya casos extremos que no funcionen, y seguramente hay mejores formas de hacerlo, pero quizás sea lo suficientemente bueno para sus propósitos.

 import difflib import sys with open('/tmp/hosts0', 'r') as hosts0: with open('/tmp/hosts1', 'r') as hosts1: diff = difflib.unified_diff( hosts0.readlines(), hosts1.readlines(), fromfile='hosts0', tofile='hosts1', n=0, ) for line in diff: for prefix in ('---', '+++', '@@'): if line.startswith(prefix): break else: sys.stdout.write(line[1:]) 
 hosts0 = open("C:path\\a.txt","r") hosts1 = open("C:path\\b.txt","r") lines1 = hosts0.readlines() for i,lines2 in enumerate(hosts1): if lines2 != lines1[i]: print "line ", i, " in hosts1 is different \n" print lines2 else: print "same" 

El código anterior está funcionando para mí. ¿Puede indicar qué error está enfrentando?

Puede agregar una statement condicional. Si su matriz va más allá del índice, rompa e imprima el rest del archivo.

 import difflib f=open('a.txt','r') #open a file f1=open('b.txt','r') #open another file to compare str1=f.read() str2=f1.read() str1=str1.split() #split the words in file by default through the spce str2=str2.split() d=difflib.Differ() # compare and just print diff=list(d.compare(str2,str1)) print '\n'.join(diff)