Comparar dos archivos reportar diferencia en python
Tengo 2 archivos llamados "hosts" (en diferentes directorios)
Quiero compararlos usando python para ver si son IDÉNTICOS. 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, obtengo
File "./audit.py", line 34, in <module>
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 mejor método para comparar 2 archivos y reportar la diferencia?
5 answers
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
Produce lo siguiente:
--- file1
+++ file2
@@ -1,7 +1,7 @@
+cat
dog
-cat
bird
buffalo
-gophers
-hound
+gopher
horse
+mouse
Esta diferencia le da contexto surrounding líneas circundantes para ayudar a aclarar cómo el archivo es diferente. Puede ver "gato" aquí dos veces, porque se eliminó de debajo de "perro" y se agregó por encima de él.
Puede usar n=0 para eliminar el contexto.
for line in difflib.unified_diff(lines1, lines2, fromfile='file1', tofile='file2', lineterm='', n=0):
print line
Dando salida a 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 hacerlo 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, ¿qué quieres que haga? Si ignora todas las líneas eliminadas, entonces no verá que" hound " se eliminó. Si estás contento mostrando las adiciones al archivo, entonces puedes 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
Probablemente ya se puede decir que hay varias formas de "imprimir las diferencias" de dos archivos, por lo que tendrá que ser muy específico si desea más ayuda.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-02 00:14:21
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 dudosa que ignora ciertas líneas. Puede haber casos extremos que no funcionan, y seguramente hay mejores maneras de hacer esto, pero tal vez 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:])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 16:36:33
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 por favor indicar a qué error se enfrenta?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-05 19:12:19
Puede agregar una instrucción condicional. Si su matriz va más allá del índice, rompa e imprima el resto 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-17 11:17:11