Python 逐行比较2个文件,忽略换行符差异

Python 逐行比较2个文件,忽略换行符差异,python,python-2.7,newline,string-comparison,Python,Python 2.7,Newline,String Comparison,我使用Python 2.7逐行比较两个文本文件,忽略: 不同的行尾('\r\n'vs'\n') 文件末尾的空行数 下面是我的代码。它适用于第2点,但不适用于第1点。我比较的文件可能很大,所以我逐行阅读。请不要建议使用zip或类似的库 def compare_files_by_line(fpath1, fpath2): # notice the opening mode 'r' with open(fpath1, 'r') as file1, open(fpath2, 'r') a

我使用Python 2.7逐行比较两个文本文件,忽略:

  • 不同的行尾('\r\n'vs'\n')
  • 文件末尾的空行数
  • 下面是我的代码。它适用于第2点,但不适用于第1点。我比较的文件可能很大,所以我逐行阅读。请不要建议使用zip或类似的库

    def compare_files_by_line(fpath1, fpath2):
        # notice the opening mode 'r'
        with open(fpath1, 'r') as file1, open(fpath2, 'r') as file2:
            file1_end = False
            file2_end = False
            found_diff = False
            while not file1_end and not file2_end and not found_diff:
                try:
                    # reasons for stripping explained below
                    f1_line = next(file1).rstrip('\n')
                except StopIteration:
                    f1_line = None
                    file1_end = True
                try:
                    f2_line = next(file2).rstrip('\n')
                except StopIteration:
                    f2_line = None
                    file2_end = True
    
                if f1_line != f2_line:
                    if file1_end or file2_end:
                        if not (f1_line == '' or f2_line == ''):
                            found_diff = True
                            break
                    else:
                        found_diff = True
                        break
    
        return not found_diff
    
    如果不满足第1点,可以测试此代码。通过向它提供2个文件,其中一个文件的行以UNIX换行符结尾

    abc\n
    
    另一个具有以Windows换行符结尾的行

    abc\r\n
    
    在每次比较之前,我都会剥离尾行字符,以说明第2点。这就解决了两个文件包含一系列相同行的问题,即使一个文件以空行结尾,而另一个文件则不以空行结尾,此代码也会将它们识别为“不不同”

    根据,以“r”模式(而不是“rb”)打开文件时应注意操作系统特定的行尾,并将它们全部读取为“\n”。这并没有发生

    如何将行结尾“\r\n”处理为“\n”结尾?

    我正在将Python 2.7.12与Anaconda发行版4.2.0一起使用。

    在open的
    'r'
    选项上,说明如下:

    The default is to use text mode, which may convert '\n' characters
    to a platform-specific representation on writing and back on
    reading. Thus, when opening a binary file, you should append 'b' to
    the mode value to open the file in binary mode, which will improve portability.
    
    因此,它是否转换端点符号取决于具体的实现,您不应该依赖它。(但是在二进制文件中,这可能会导致一些问题,因此使用了
    'b'
    选项)

    我们可以通过将
    rstrip
    函数更改为
    f1\u line.rstrip('\r\n')
    来解决此问题。这样,所有平台上的线端都会被强制移除

    我在下面创建了您的程序的简化版本:

    from itertools import izip
    
    def compare_files(fpath1, fpath2):
        with open(fpath1, 'r') as file1, open(fpath2, 'r') as file2:
            for linef1, linef2 in izip(file1, file2):
                linef1 = linef1.rstrip('\r\n')
                linef2 = linef2.rstrip('\r\n')
    
                if linef1 != linef2:
                    return False
            return next(file1, None) == None and next(file2, None) == None
    

    请不要把这两个文件压缩在一起。它看起来更好,但我更喜欢避免使用大文件。我知道也有izip,但请保持基本。您确定“\r\n”同时为“\r\n”和“\n”工作吗?您可以在REPL中自己测试它。另外,我个人更喜欢拉链,但是,你是对的,izip会更好。它很管用!没想到rstrip会这样工作!它也适用于“\n\r”!谢谢你,伙计!顺便说一句,在“r”模式下打开文件仍然会保留操作系统特定的端点,这没关系吧?