我有2個(大)文件。第一個約20萬線,第二個約3千萬線。如何在Perl中匹配來自兩個大文件的數據?
我想檢查第一個的每一行是否在第二個使用Perl。 將第一行的每一行與第二行的每一行進行比較會更快嗎?還是更好地將它們全部存儲在兩個不同的數組中,然後操作數組?
我有2個(大)文件。第一個約20萬線,第二個約3千萬線。如何在Perl中匹配來自兩個大文件的數據?
我想檢查第一個的每一行是否在第二個使用Perl。 將第一行的每一行與第二行的每一行進行比較會更快嗎?還是更好地將它們全部存儲在兩個不同的數組中,然後操作數組?
將第一個文件的行存儲在散列中,然後迭代第二個文件而不將其存儲在內存中。
存儲第一個文件並迭代第二個文件可能會違反直覺,反之亦然,但它可以避免創建一個3000萬個元素的散列。
use feature 'say';
my ($path_1, $path_2) = @ARGV;
open my $fh1,"<",$path_1;
my %f1;
$f1{$_} = $. while (<$fh1>);
open my $fh2,"<",$path_2;
while (<$fh2>) {
if (my $f1_line = $f1{$_}) {
say "file 1 line $f1_line appears in file 2 line $.";
}
}
注意,而無需進一步處理,重複的線將在它們出現在第二個文件,而不是第一順序顯示。
此外,假定文件1沒有重複的行,但可以根據需要進行處理。
謝謝!我的第一個測試給了我45秒的執行時間。我現在必須改善我的搜索範圍,但我認爲這不會延長執行時間:) – VeZoul
你有文件和文件B.你要檢查,如果在文件中的線條出現在文件B.
如果你有足夠的內存使用每行一個條目的哈希持有文件B的內容,這是最簡單的。前進。
但是,如果您不這樣做,我建議您將兩個文件放在SQL數據庫的表中。 SQLite可能足以啓動。那麼,你的問題就簡化爲一個簡單的JOIN
。如果行長度有問題,請使用快速散列,如xxHash。如果正確實施,64位版本在64位機器上快速發展,特別是如果您在Perl中啓用了優化。存儲兩列,散列和實際行。如果散列匹配,請檢查這些行是否匹配。確保在哈希列上進行索引。
你說:
事實上,我的文件是這樣的:文件:名稱數量(每行)文件B:(每行)名稱日期位置號碼,我要檢查,如果文件B包含與文件A的數據匹配的行(忽略日期和位置,例如)所以它不是完全匹配...
在這種情況下,您已設置。你甚至不必擔心哈希的東西(我將離開這裏作爲參考)。將需要匹配的數據的有趣部分放在SQLite數據庫的單獨列中。寫一個連接。利潤。
或者,您可以使用BerkeleyDB,它可讓您在將表存儲在磁盤上時具有內存散列的概念性簡單性。如果您有多個要匹配的屬性,則這不會很好地擴展。
如果行數可能比SQL數據庫可用作索引的時間長,則這將不起作用。 –
@MarkusLaire True。更新了我的答案。 –
我必須在沒有連接到任何服務器或本地主機的計算機上運行程序。所以唯一的方法是內存存儲... – VeZoul
...還是有更好的方法,就像使用哈希? – mob
就像在散列中存儲了3千萬行並檢查每條200k行是否在其中? – VeZoul
好吧,我的情況有點特殊。事實上,我的文件是這樣的: 文件A:名稱編號(每行) 文件B:名稱日期位置編號(每行) 而且我必須檢查文件B是否包含與文件A的數據匹配的行(忽略日期和位置例如) 所以它不是一個完全匹配,必須先應用一個處理 – VeZoul