【问题标题】:Comparing 2 files line by line逐行比较2个文件
【发布时间】:2013-03-14 04:23:36
【问题描述】:

我有 2 个格式如下的文件:

file1:
work1
7 8 9 10 11
1 2 3 4  5
6 7 8 9  10

file2:
work2
2 3 4 5 5
2 4 7 8 9
work1
7 8 9 10 11
1 2 4 4  5
6 7 8 9  10
work3
1 7 8 9 10

现在我想与文件进行比较,并且无论标题(work1)是否相等..我想比较后续部分并打印发现差异的行。例如

 work1 (file1)
7 8 9 10 11
1 2 3 4  5
6 7 8 9  10

work1 (file2)
7 8 9 10 11
1 2 4 4  5
6 7 8 9  10

现在我想打印出现差异的行,即“1 2 4 4 5”

为此,我编写了以下代码:

with open("file1",) as r, open("file2") as w:
    for line in r:
        if "work1" in line:
            for line1 in w:
                if "work1" in line1:
                        print "work1"

但是,从这里开始,我对如何同时读取这两个文件感到困惑。有人可以帮我解决这个问题...因为在比较“work1”之后我没有得到我应该如何并行读取文件

【问题讨论】:

  • 将两者都读入内存(每个 r.read() 和 w.read() 都读入一个变量),然后进行比较。并行不是正确的词。
  • CppLearner 该方法只有在我的文件不大的情况下才可行,对于大文件该方法不可行
  • 好点。好吧,如果您确定 work1 之类的标头不会在同一个文件中重复,那么您可以打开文件并读取子字符串出现和结束的位置以及下一个标头出现的位置。将它们记录在两个文件中,然后阅读。我不知道性能与 stackoverflow.com/questions/3322419/… 相比如何,后者将两个文件读入同一个迭代器。
  • 看起来像是数据库的工作。
  • 你的目标是模仿diff 比如winmerge.org 吗?或者你只关心第一个区别,然后退出?

标签: python python-2.7


【解决方案1】:

您可能想在 Python 中试用 @987654321@ 模块。 它包含一个名为izip 的函数,可以满足您的需求,还有一个名为islice 的函数。您可以遍历第二个文件,直到找到您要查找的标头,然后您可以将标头切片。

这里有一些代码。

from itertools import *    

w = open('file2')
for (i,line) in enumerate(w):
  if "work1" in line:
    iter2 = islice(open('file2'), i, None, 1) # Starts at the correct line

f = open('file1')
for (line1,line2) in izip(f,iter2):
  print line1, line2 # Place your comparisons of the two lines here.

您现在可以保证,在循环的第一次运行中,您将在两行上都获得“work1”。之后就可以比较了。由于fw 短,因此迭代器将耗尽自身并在您到达f 的末尾时停止。

希望我解释得很好。

编辑:添加导入语句。

编辑:我们需要重新打开 file2。这是因为在 Python 中遍历可迭代对象会消耗可迭代对象。所以,我们需要将一个全新的传递给islice,这样它才能工作!

【讨论】:

  • islice(w, i, None, 1) 从文件中的当前位置开始跳过i 行。
  • @AVP 谢谢回复...你能解释一下“islice”的功能吗?实际上它给了我错误..name 'islice' 没有定义。我也导入了 itertools..我仍然不明白为什么它会抛出错误
  • 你是在做 itertools.islice 还是在做 islice?只有当您的导入语句是“from itertools import *”时,第二个才有效,而当您执行“import itertools”时,第一个才有效。
  • 我的问题是“for (line1,line2) in izip(f,iter2): print line1, line2”这里没有打印任何行。非常感谢您的帮助
  • 尝试简单地遍历 iter2。那会打印什么吗?
【解决方案2】:
with open('f1.csv') as f1, open('f2.csv') as f2 :
    i=0
    break_needed = False
    while True :
        r1, r2 = f1.readline(), f2.readline()
        if len(r1) == 0 :
            print "eof found for f1"
            break_needed = True
        if len(r2) == 0 :
            print "eof found for f2"
            break_needed = True
        if break_needed : 
            break
        i += 1
        if r1 != r2 :
            print " line %i"%i
            print "file 1 : " + r1
            print "file 2 : " + r2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 2017-04-06
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    相关资源
    最近更新 更多