2016-05-16 50 views
0

嗯,我的問題是非常簡單的,但我沒有找到正確的答案在哪裏。我需要的是找到一個。方式讀取一個txt文件,如果有重複的線路,將它們全部刪除,不保留一個例如,在一個.txt包含以下內容:如何刪除文件中使用PHP(包括「原」)重複行?

1234 
1233 
1232 
1234 

輸出應該是:

1233 
1232 

因爲代碼必須刪除重複的行,所有這些。我搜索了所有的網頁,但它總是指向rem的答案ove複製線但保留其中的一個,如thisthisthat

恐怕唯一的方法就是讀取x行並檢查整個.txt文件,如果找到相同的結果,刪除和刪除x行。如果不是,則切換到下一行。但是我檢查的.txt文件有五千萬行(〜900Mb),我不知道我需要做多少內存來完成這種任務,所以我非常感謝這裏的一些幫助。

+0

我會感興趣,如果你可以測試特別是對於它的內存佔用我的解決方案... :) –

+0

輸出文件中行的順序是否重要? – Mike

+0

感謝您的努力,您的代碼可以使用小文件,但我無法用5千萬條目測試您的代碼,因爲我沒有足夠的內存... –

回答

3

逐行讀取文件中的行,並使用行內容作爲關聯數組其值的次出現的行數的計數的關鍵。完成後,寫出所有隻有1的行。這將需要與所有獨特行一樣多的內存。

$lines = array(); 
$fd = fopen("inputfile.txdt", "r"); 
while ($line = fgets($fd)) { 
    $line = rtrim($line, "\r\n"); // ignore the newline 
    if (array_key_exists($line, $lines)) { 
     $lines[$line]++; 
    } else { 
     $lines[$line] = 1; 
    } 
} 
fclose($fd); 
$fd = fopen("outputfile.txt", "w"); 
foreach ($lines as $line => $count) { 
    if ($count == 1) { 
     fputs($fd, "$line" . PHP_EOL); // add the newlines back 
    } 
} 
+0

需要注意的是,如果沒有多少重複,OP將需要相當多的RAM,因爲他擁有900MB的數據。此外,如果線條平均時間足夠長,則可以使用line的散列而不是其內容本身作爲數組鍵。 –

+0

@dragoste是的,但它比在刪除所有重複項之前將整個文件讀入內存的答案要好。由於他的例子中有短線,我決定不打算顯示一個更適合長線的解決方案。 – Barmar

+0

是的,它更好,這就是爲什麼我選擇了你的答案來指出我的想法。 –

0

我懷疑是否有一個功能可以完成所有你想做的事情。所以,這將其分解成幾個步驟...

首先,我們可以直接將文件加載到數組中嗎?請參閱file命令

$lines = file('mytextfile.txt'); 

文檔現在,我都在陣列中的線。我想統計每個條目的數量。請參閱array_count_values命令的文檔。現在

$counts = array_count_values($lines); 

,我很容易循環通過陣列和刪除其中計數> 1

foreach($counts as $value=>$cnt) 
    if($cnt>1) 
    unset($counts[$value]); 

現在,我可以把數組鍵(這是值)到一個數組任何條目。

$nondupes = array_keys($counts); 

最後,我可以寫出內容到一個文件。

file_put_contents('myoutputfile.txt', $nondupes); 
+0

您打算在CLI或瀏覽器中執行此代碼嗎?我建議在CLI中執行,不要觸及PHP內存和時間限制。 –

+0

@AmbroiseMaupate如果他通過網絡解析了5000萬行,他將通過默認安裝命中內存或時間限制。那是他的錯。 – kainaw

+0

如果他將所有這些數據添加到SQL數據庫會怎麼樣?然後他可以創建一個簡單的SQL查詢來查找重複的條目。只有一個SQLite,它不需要任何額外的設置(如果他設置php-sqlite擴展)。 –

0

我想我有一個解決方案更爲優雅:

$array = array('1', '1', '2', '2', '3', '4'); // array with some unique values, some not unique 

$array_count_result = array_count_values($array); // count values occurences 

$result = array_keys(array_filter($array_count_result, function ($value) { return ($value == 1); })); // filter and isolate only unique values 

print_r($result); 

給出:

Array 
(
    [0] => 3 
    [1] => 4 
)