Подтвердить что ты не робот

Сравнение двух различий отчетов в python

У меня есть 2 файла под названием "hosts" (в разных каталогах)

Я хочу сравнить их с помощью python, чтобы узнать, являются ли они ИДЕНТИЧНЫМИ. Если они не идентичны, я хочу напечатать разницу на экране.

До сих пор я пробовал это

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"

Но когда я запускаю это, я получаю

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

Это означает, что один из хостов имеет больше строк, чем другой. Есть ли лучший способ сравнить 2 файла и сообщить о различии?

4b9b3361

Ответ 1

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

Выводит следующее:

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

Этот diff дает вам контекстные линии, чтобы помочь понять, как этот файл отличается. Вы можете увидеть "кошку" здесь дважды, потому что она была удалена снизу "собака" и добавлена ​​над ней.

Вы можете использовать n = 0 для удаления контекста.

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

Вывод:

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

Но теперь он заполнен строками "@@", в которых вам указана позиция в файле, который изменился. Позвольте удалить дополнительные строки, чтобы сделать его более читаемым.

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

Предоставление нам этого результата:

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

Теперь, что вы хотите сделать? Если вы проигнорируете все удаленные строки, вы не увидите, что "собака" была удалена. Если вы счастливы, просто показывая дополнения к файлу, вы можете сделать это:

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

Выведение:

additions:
cat
gopher
mouse

additions, ignoring position:
gopher
mouse

Вероятно, вы уже можете сказать, что существуют различные способы "распечатать различия" двух файлов, поэтому вам нужно будет быть очень конкретным, если вам нужна дополнительная помощь.

Ответ 2

Библиотека difflib полезна для этого и входит в стандартную библиотеку. Мне нравится унифицированный формат diff.

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)

Выходы:

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

И вот хитрая версия, которая игнорирует определенные строки. Там могут быть краевые случаи, которые не работают, и, безусловно, есть лучшие способы сделать это, но, возможно, это будет достаточно для ваших целей.

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:])

Ответ 3

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"

Приведенный выше код работает для меня. Можете ли вы указать, с какой ошибкой вы сталкиваетесь?

Ответ 4

Вы можете добавить условный оператор. Если ваш массив выходит за пределы индекса, то перерыв и печать остальной части файла.

Ответ 5

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)