比较两个文本文件,删除重复的行,并将结果写入新的文本文件

时间:2011-08-04 14:56:57

标签: python compare lines

我有两个文本文件(行数/大小不相等)。我想将较短文本文件的每一行与较长文本文件的每一行进行比较。比较一下,如果有任何重复的字符串,我想删除它们。最后,我想将结果写入新的文本文件并打印内容。

是否有一个简单的脚本可以为我做这个?

非常感谢任何帮助。

文本文件不是很大。一个有大约10行,另一个有大约5.我试过的代码(失败的代码)是:

for line in file2:
line1 = line
for line in file1:
    requested3 = file('request2.txt','a')
    if fnmatch.fnmatch(line1,line):
        line2 = line.replace(line,"")
        requested3.write(line2)
    if not fnmatch.fnmatch(line1,line):
        requested3.write(line+'\n')


    requested3.close()

5 个答案:

答案 0 :(得分:4)

with open(longfilename) as longfile, open(shortfilename) as shortfile, open(newfilename, 'w') as newfile:
    newfile.writelines(line for line in shortfile if line not in set(longfile))

就这么简单。这会将shortfile行复制到newfile,而不必将它们全部保留在内存中(如果它们也存在于longfile中。

如果您使用的是Python 2.6或更早版本,则需要嵌套with语句:

with open(longfilename) as longfile: 
    with open(shortfilename) as shortfile:
        with open(newfilename, 'w') as newfile:

如果您使用的是Python 2.5,则需要:

from __future__ import with_statement 

在您文件的非常顶级,或者只使用

longfile = open(longfilename) 

等。并自己关闭每个文件。

如果你需要操纵这些线,一个明确的for循环很好,重要的部分是set()。查找集合中的项目很快,查找长列表中的行很慢。

longlines = set(line.strip_or_whatever() for line in longfile)
for line in shortfile:
    if line not in longlines:
        newfile.write(line)

答案 1 :(得分:2)

假设文件都是纯文本,则每个字符串都位于以\ n换行符分隔的新行上:

small_file = open('file1.txt','r')
long_file = open('file2.txt','r')
output_file = open('output_file.txt','w')

try:
    small_lines = small_file.readlines()
    small_lines_cleaned = [line.rstrip().lower() for line in small_lines]
    long_file_lines = long_file.readlines()
    long_lines_cleaned = [line.rstrip().lower() for line in long_lines]

    for line in small_lines_cleaned:
        if line not in long_lines_cleaned:
            output_file.writelines(line + '\n')

finally:
    small_file.close()
    long_file.close()
    output_file.close()

说明:

  1. 由于您无法使用'with'语句,我们首先使用常规打开函数打开文件,然后使用try ... finally子句在程序结束时关闭它们。
  2. 我们获取小文件和长文件,然后首先使用.rstrip()删除任何尾随的'\ n'(换行符)字符,然后使用.lower()将所有字符设置为小写。如果你有两个句子在每个方面相同,除了一个大写字母而另一个没有,他们就不匹配。强迫它们小写避免了这种情况;如果您更喜欢区分大小写的比较,请删除.lower()方法。
  3. 我们逐行在small_lines_cleaned中(对于......中的行)并查看它是否在较大的文件中。
  4. 如果不在较长的文件中,则输出每一行;我们添加'\ n'换行符,以便每一行都出现在一个新行上,而不是OOOneGiantLongSetOfStrings

答案 2 :(得分:1)

我使用difflib,它可以很容易地进行比较/差异。有一个很好的教程here。如果您只想要较短文件所特有的行:

from difflib import ndiff

short = open('short.txt').readlines()
long = open('long.txt').readlines()

with open('unique.txt', 'w') as f:
    f.write(''.join(x[2:] for x in ndiff(short, long) if x.startswith('-')))

答案 3 :(得分:0)

您的代码将检查每一行与另一个文件中的行。但那不是你想要的。对于第一个文件中的每一行,您需要检查另一个文件中的任何行是否匹配,如果没有匹配则打印出来。

答案 4 :(得分:0)

以下代码读取文件2并将其与文件1进行比较。文件1 中但文件2 中的所有内容都将被打印并写入新文本文件。

如果您想做相反的事情,则只需摆脱下面if语句中的“ not”。因此,它将打印文件一文件二中的任何内容。

通过将较短文件(文件2)的内容放入变量,然后逐行读取较长文件(文件1),可以工作。根据变量检查每一行,然后根据变量中是否存在该行将其写入或不写入文本文件。

(如果要使用,请记住除去not语句周围的星号;如果要打印匹配的单词,请一起除去not语句。)

fileOne = open("LONG FILE.ext","r")
fileTwo = open("SHORT FILE.ext","r")
fileThree = open("Results.txt","a+")

contents = fileTwo.read()

numLines = sum(1 for line in fileOne)
for i in range (numLines):
    if **not** fileOne.readline(i) in contents:
        print (fileOne.readline(i))
        fileThree.write (fileOne.readline(i))
        
fileOne.close()
fileTwo.close()
fileThree.close()