web-dev-qa-db-ja.com

2つのファイルを比較して、python

「hosts」と呼ばれる2つのファイルが(異なるディレクトリに)あります

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

つまり、ホストの1つが他のホストよりも多くの行を持っています。 2つのファイルを比較し、違いを報告するより良い方法はありますか?

33
Masster
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はコンテキストを提供します-周囲の行は、ファイルの違いを明確にするのに役立ちます。 「cat」は、「dog」の下から削除され、その上に追加されたため、ここに2回表示されます。

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つのファイルの「違いを印刷する」ためのさまざまな方法があることをおわかりでしょう。したがって、さらにヘルプが必要な場合は、非常に具体的にする必要があります。

56
rbutcher

Difflibライブラリはこれに役立ち、標準ライブラリに含まれています。統一された差分形式が好きです。

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

そして、特定の行を無視する危険なバージョンがあります。動作しないEdgeケースが存在する可能性があり、これを行うためのより良い方法は確かにありますが、おそらく目的には十分でしょう。

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:])
11
rbutcher
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"

上記のコードは私のために働いています。直面しているエラーを教えてください。

3
Raj
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)
1
Azad Mehla

条件ステートメントを追加できます。配列がインデックスを超える場合は、ファイルの残りを分割して印刷します。

1
user2835809