我正在使用Python 2.6,我想创建一个简单的GUI,其中包含两个并排的文本窗格,比较两个文本文件(file1.txt和file2.txt)。
我正在使用difflib,但我不清楚如何生成类似于sdiff Unix命令的结果。
为了重现并排比较,我需要difflib来返回两个变量file1_diff
和file2_diff
。
我还考虑过直接使用sdiff输出并解析它来分隔窗格,但事实证明它并不像看起来那么容易......任何提示?
答案 0 :(得分:1)
您可以使用 difflib.Differ 返回单个行序列,在每行的开头带有一个标记来描述该行。标记会告诉您有关该行的以下信息:
标记 | 说明 |
---|---|
'- ' |
文件 1 独有的行 |
'+ ' |
文件 2 独有的行 |
' ' |
两个文件共有的行 |
'? ' |
输入文件中不存在该行 |
您可以使用此信息来决定如何显示数据。例如,如果标记是
,则将线同时放在左右小部件中。如果它是 +
,您可以在左侧放置一个空行,在右侧放置实际行,表明该行对于右侧的文本是唯一的。同样,-
表示该行在左侧是唯一的。
例如,您可以创建两个文本小部件 t1
和 t2
,一个用于左侧,一个用于右侧。您可以通过为每个文件创建一个行列表,然后将它们传递给不同的 compare
方法,然后迭代结果来比较两个文件。
t1 = tk.Text(...)
t2 = tk.Text(...)
f1 = open("file1.txt", "r").readlines()
f2 = open("file2.txt", "r").readlines()
differ = difflib.Differ()
for line in differ.compare(f1, f2):
marker = line[0]
if marker == " ":
# line is same in both
t1.insert("end", line[2:])
t2.insert("end", line[2:])
elif marker == "-":
# line is only on the left
t1.insert("end", line[2:])
t2.insert("end", "\n")
elif marker == "+":
# line is only on the right
t1.insert("end", "\n")
t2.insert("end", line[2:])
上面的代码忽略带有标记 ?
的行,因为这些是额外的行,它们试图引起人们对前一行不同字符的注意,并且实际上不是任何文件的一部分。如果您愿意,您可以使用该信息突出显示各个字符。
答案 1 :(得分:0)
这样的事情怎么样?
>>> a = ['cat', 'dog', 'horse']
>>> b = ['cat', 'horse', 'chicken']
>>> comparison = list(l for l in difflib.Differ().compare(a,b) if not l.startswith('?'))
>>> left = [l[2:] if l.startswith((' ', '-')) else '' for l in comparison]
>>> right = [l[2:] if l.startswith((' ', '+')) else '' for l in comparison]
>>> left
['cat', 'dog', 'horse', '']
>>> right
['cat', '', 'horse', 'chicken']
答案 2 :(得分:-2)
我已尝试使用difflib.context_diff执行文件差异:
diff = difflib.context_diff(fromlines, tolines, fromfile='file1.txt', tofile='file2.txt')
sys.stdout.writelines(diff)
在这种情况下,您的输出将是这样的:
*** file1.txt
--- file2.txt
***************
*** 1,6 ****
! aasdf
qwer
123
! poiu
! xzcv34
xzcv
--- 1,6 ----
! asdf
qwer
+ mnbv
123
! cvnn
xzcv
在这种情况下,您可以轻松地分离每个文件差异,但我不确定您是否会对context_diff的输出感到满意。您还没有提到您使用difflib的方式。