2012-07-09 55 views
0

我寫了一個perl腳本,它讀取2個不同的文件,比較這兩個文件中的ID並僅打印ID匹配的數據。 ID文件被讀入一個數組,而數據文件被逐行讀取。這一切都工作得很好,但現在我需要添加更多。在我的數據文件中,有時候我會有行重複的ID,因爲主題已經有多次訪問提供樣本。因此,我需要查找這些重複項目,並只採取最新的訪問日期。搜索特定的重複ID的

所以我的數據文件看起來是這樣的:

ID DOV Data1 Data2 etc etc 

現在,我已經看到了哈希值是搜索重複的方式,但所有我見過一直簡單地胡亂刪除重複的修復,這不是我想要的。

任何想法?

+2

閱讀所有行到哈希由ID,覆蓋任何以前的值。如果輸入未按DOV排序,則需要添加比較,並且只有在新值更新時才進行替換。然後在最後打印出散列。 (假設「DOV」代表「訪問日期」。) – tripleee 2012-07-09 11:41:20

+0

@tripleee您是指將整個文件一次讀入散列或逐行讀取?我從來沒有使用過散列,所以如果你能給出一個你的意思很好的例子! – Michelle 2012-07-09 13:04:30

回答

0
# read id file 
my %id_hash; 
while (<IDFILE>) { 
    chomp; 
    $id_hash{$_} = 1; 
} 

#read data file 
while (<DATAFILE>) { 
    my @arr = split(/\s+/, $_); 
    if (defined $id_hash{$arr[0]}) { # only process if exists in id file 
    # and only if this is the first data entry or a later visit 
    if ((not ref $id_hash{$arr[0]}) or ($id_hash{$arr[0]}[1] < $arr[1])) { 
     # store all data in an array ref 
     $id_hash{$arr[0]} = [ @arr ]; 
    } 
    } 
} 

for my $id (keys %id_hash) { 
    print join(" ", @{$id_hash{$id}}), "\n"; 
} 
+0

謝謝!你解釋得很好,你實際上已經設法做我在原始腳本中做的事情,代碼少得多!這是一個學習曲線! – Michelle 2012-07-10 11:28:07

0

這將顯示每個ID的最後一個DOV,對輸入數據做出假設lot,所以很有可能它不適合您。 (特別是,如果您的輸入數據沒有按日期排序,它將根本無法工作,因爲它只是爲每個ID顯示最後一個日期。而且,如果日期的格式化方式包含空格,例如「 Mon Jul 9 15:51:22 CEST 2012「,它只會得到第一個空間的日期(本例中的」Mon「)。)這裏的要點只是爲了演示基本技術,而不是提供完整的解決方案。

#!/usr/bin/env perl  

use strict; 
use warnings; 

my %visit; 
while (<DATA>) { 
    my ($id, $date) = split; 
    $visit{$id} = $date; 
} 

for my $id (sort keys %visit) { 
    print "$id => $visit{$id}\n"; 
} 

__DATA__ 
1  2012-01-01 
2  2012-01-02 
1  2012-02-03 
3  2012-02-04 
2  2012-03-05 
3  2012-03-06 
4  2012-04-07 
1  2012-04-08 
5  2012-05-09 
1  2012-05-10