2012-02-27 74 views
-2

說我有一個很大的文件「done.txt」如何刪除已經包含在另一條線路

然後,我有另一家大型文件「post.txt」

我想擺脫所有行所有post.txt文件中已存在的文件位於done.txt中

我不想在內存中加載done.txt的所有內容。我會怎麼做?

100%的準確性並不重要。

+1

什麼語言/環境?貝殼? PHP? VBScript的?請詳細說明。 – Graham 2012-02-27 03:58:11

+0

可能出現[從另一個文件中出現的文件中刪除行]的副本(http://stackoverflow.com/questions/4366533/remove-lines-from-file-which-appear-in-another-file) – 2013-03-14 21:35:01

回答

1

由於不需要100%的準確性,所以可以將所有行散列在done.txt中,並將這些散列的集合(數組,列表,等等)保存在內存中。

然後,處理post.txt中的每一行。如果該行的散列與您已有的散列匹配,請將其丟棄。

會出現誤報(即使它們是而不是done.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中的行不匹配任何散列,那麼它就不可能是重複的,所以你要保留它。

如果確實匹配的哈希,再有就是它是一個重複的一個可能性。然後使用該散列條目的一個或多個文件偏移量對被測試的行與done.txt中的行進行二進制比較(通過閱讀實際行)。如果在那裏找到一場比賽,這是一個騙局,所以你扔掉線,否則你保留它。

這減少了內存中的存儲空間(當然,除了post.txt之外的行,不過它們是不管需要的),還是至少有一行是從done.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文件中的實際行?計算機將逐行逐行讀取。那是O(n)。哈希似乎是正確的方向。哈希本身已經減少了內存使用量。 – 2012-02-27 03:47:30

+0

@Jim,大多數語言都會有一個查找類型的操作,您可以首先查找特定的文件偏移量。您只需查找存儲的偏移量,然後讀取一行。您不需要同時在內存中存儲整個5G文件,每次只需一行。如果您唯一的興趣是在第314159行,您也不必閱讀第1行到第314158行。您將知道散列條目的偏移量。事實上,你不知道的是行號,這些信息並不存儲在'done.txt'處理中,也不是必需的。 – paxdiablo 2012-02-27 03:53:45

+0

哦....是的,我正在尋找vb.net。這是語言。 – 2012-02-27 04:15:01