說我有一個很大的文件「done.txt」如何刪除已經包含在另一條線路
然後,我有另一家大型文件「post.txt」
我想擺脫所有行所有post.txt文件中已存在的文件位於done.txt中
我不想在內存中加載done.txt的所有內容。我會怎麼做?
100%的準確性並不重要。
說我有一個很大的文件「done.txt」如何刪除已經包含在另一條線路
然後,我有另一家大型文件「post.txt」
我想擺脫所有行所有post.txt文件中已存在的文件位於done.txt中
我不想在內存中加載done.txt的所有內容。我會怎麼做?
100%的準確性並不重要。
由於不需要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
有一個這個問題。你如何閱讀5 GB文件中的實際行?計算機將逐行逐行讀取。那是O(n)。哈希似乎是正確的方向。哈希本身已經減少了內存使用量。 – 2012-02-27 03:47:30
@Jim,大多數語言都會有一個查找類型的操作,您可以首先查找特定的文件偏移量。您只需查找存儲的偏移量,然後讀取一行。您不需要同時在內存中存儲整個5G文件,每次只需一行。如果您唯一的興趣是在第314159行,您也不必閱讀第1行到第314158行。您將知道散列條目的偏移量。事實上,你不知道的是行號,這些信息並不存儲在'done.txt'處理中,也不是必需的。 – paxdiablo 2012-02-27 03:53:45
哦....是的,我正在尋找vb.net。這是語言。 – 2012-02-27 04:15:01
什麼語言/環境?貝殼? PHP? VBScript的?請詳細說明。 – Graham 2012-02-27 03:58:11
可能出現[從另一個文件中出現的文件中刪除行]的副本(http://stackoverflow.com/questions/4366533/remove-lines-from-file-which-appear-in-another-file) – 2013-03-14 21:35:01