2012-02-27 2 views
-2

は私が私は取り除きたいすでに

は、その後、私は別の大きなファイル「post.txtを」持っている「done.txt」大きなファイルを持っていると言う別の行に含まれているすべての行を削除する方法既にdone.txtにあるpost.txt内のすべての出現

私はdone.txtのすべてのコンテンツをメモリにロードしたくありません。どうすればいい?

精度は重要ではありません。

+1

何語/環境:ようなものになるだろう

?シェル? PHP? VBScript?もっと詳しく、してください。 – Graham

+0

[別のファイルに表示されるファイルから行を削除]の可能な複製(http://stackoverflow.com/questions/4366533/remove-lines-from-file-which-appear-in-another-file) –

答えて

1

100%の精度は必須ではないので、すべての行をdone.txtにハッシュし、それらのハッシュのコレクション(配列、リストなど)をメモリ内に保持できます。

次に、すべての行をpost.txtに処理します。その行のハッシュが既に持っているものと一致する場合は、それを放棄してください。

ではなくではないにもかかわらず、偽陽性がありますが、偽陰性はありません。

ような何か:

hash = [] 

for each line in done.txt: 
    hashVal = makeHash (line) 
    hash[hashVal] = true 

for each line in post.txt: 
    hashVal = makeHash (line) 
    if not defined hash[hashVal]: 
     print line 

それとも、あなたは最小限のメモリ内のストレージと100%の精度が必要な場合は、ハッシュあたりのファイルオフセットのコレクションと一緒にハッシュを保ちます。

post.txtの行がいずれのハッシュとも一致しない場合は、重複している可能性はないのでそのまま使用してください。

の場合、はハッシュと一致し、の可能性があります。は重複しています。そのハッシュエントリに対して1つまたは複数のファイルオフセットを使用して、実際の行を読み取って、done.txtの行に対してテストされている行のバイナリ比較を実行します。そこにマッチが見つかった場合は、そのママがそのラインを投げ捨てるので、そうしないとあなたはそれを保持します。

これは、ハッシュ付きラインオフセットコレクションと、最大でdone.txtからの1行のat-memoryストレージ(もちろん、post.txtの行以外は必要ですが)を削減します。潜在的な余分なI/Oのコスト。

しかし、私は「100%精度未満」という大きなファンではないので、それはおそらく行くだろう。

hash = [] 

fileOffset = 0 
for each line in done.txt: 
    hashVal = makeHash (line) 
    if not defined hash[hashVal]: 
     hash[hashVal] = new list() 
    hash[hashVal].append (fileOffset) 
    fileOffset = fileOffset + line.length() 

for each line in post.txt: 
    hashVal = makeHash (line) 
    printIt = true 
    if defined hash[hashVal]: 
     for each offset in hash[hashVal]: 
      read chkLine from done.txt starting at offset 
      if line == chkLine: 
       printIt = false 
    if printIt: 
     print line 
+0

この問題。 5 GBのファイルで実際の行をどのように読むのですか?コンピュータは行ごとに行を1つずつ読み込みます。それはO(n)です。ハッシュは正しい方向に見えます。ハッシュ自体はすでにメモリ使用量を減らしています。 –

+0

@ Jimでは、ほとんどの言語は、最初に特定のファイルオフセットを探すことができるシークタイプの操作を持ちます。あなたは単に格納されたオフセットを探して、行を読みます。 5Gファイル全体を一度にメモリに保存する必要はありません。唯一の関心が行314159にある場合は、行1から行314158まで読む必要はありません。ハッシュエントリからのオフセットを知ることができます。実際にあなたが知っていることは、行番号であり、その情報は 'done.txt'処理には格納されず、必要でもありません。 – paxdiablo

+0

ああ....はいvb.netは私が探しているものです。それが言語です。 –

関連する問題