2011-08-04 5 views
3

2つのテキストファイル(行数/サイズが等しくない)があります。短いテキストファイルの各行と長いテキストファイルのすべての行を比較したいと思います。比較すると、重複する文字列がある場合、それらを削除したいと思います。最後に、結果を新しいテキストファイルに書き込んで内容を印刷したいと思います。2つのテキストファイルの比較、重複する行の削除、および新しいテキストファイルへの結果の書き込み

私のためにこれを行うことができる単純なスクリプトはありますか?

ご協力いただければ幸いです。

テキストファイルはあまり大きくありません。 (それが無残に失敗した)一つは、約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() 
+0

短いテキストファイルから文字列を差し引いて短いテキストファイル長いテキストファイルにはありますか?また、これらのファイルはどれぐらいの大きさで、これまでにどのようなコードを書いていますか? – chris

答えて

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 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) 
+0

ライブラリをインポートする必要はありますか?私のコードはwith文を認識していませんか? – Katie

+0

あなたのポストを更新して、使用しているPythonのバージョンをお知らせください。あなたのコマンドラインからPythonを実行すると、バージョン(例:Python 2.7.1、Python 2.6など) – chris

+0

Python 2.5の状況を明確にするために私の答えを編集しました。 – agf

0

私は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('-'))) 
+0

これは、OPが探している種類の比較ではありません。 –

+0

@Winston Ewert:difflibは、OPがやりたい比較の種類をサポートしていませんか?どのように?それは単なるテキストです。 – hughdbrown

+0

@hughdbrown、difflibは、一方のファイルが他方のファイルの変更バージョンで、その変更を探したい場合に適用されます。私はOPがそうしているとは思わない。 –

0

あなたのコード、それはチェックし、他のファイル内の行に対するそれぞれの行を立って。しかし、それはあなたが望むものではありません。最初のファイルの各行について、他のファイルの行が一致するかどうかを確認し、一致するものがない場合はそれを出力する必要があります。

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. あなたは「で」取得することはできませんので、文を実行するには、通常のオープン関数を使用して最初にファイルを開き、try ... finally句を使用してプログラムの最後に閉じます。
  2. 小さいファイルと長いファイルを取り出し、最初に.rstrip()で末尾の '\ n'(改行)文字を削除し、すべての文字を.lower()で小文字にします。1つの大文字が大文字で、2つの文が同じでなければ、大文字と小文字は一致しません。強制的に小文字にすることは避けます。大文字と小文字を区別する比較を使用する場合は、.lower()メソッドを削除します。
  3. small_lines_cleaned(line in ...)の行ごとに、大きなファイルに含まれているかどうかを確認します。
  4. 各行が長いファイルにない場合は出力します。 '\ n'改行文字を追加して、各行が新しい行に表示されるようにします.OffOneGiantLongSetOfStrings
+0

あなたは行をたくさん修正することはOKだと思っています... 'rstrip()'は見ることができますが、 'lower()'は意味を変えることができます。長いリストを見ても遅いです。これはまさに 'set()'のためのものです。 – agf

+0

.lower()の目的をより明示的に記述するために記述を編集しました(したがって不要な場合は削除できます)。また、長いファイルには10行しか書かれていないため、スピードの問題はほとんどありません。わかりやすく読みやすいようにしました。 – chris

+0

ありがとうございます。私はこれを数日間やろうとしています。それは完璧だ。 – Katie

関連する問題