2013-05-31 134 views
3

我想寫一個perl程序,該程序讀取文件並提取其中的日期。但是,如果日期超過一次,我只會打印一次。例如:從文件中提取單詞但每個單詞一次

On 01/10/2011 I went home. On 02/02/2012, I 
went to my school. On 02/02/2012, I went 
to London. 

輸出應該是:

01/10/2011 
02/02/2012 

我可以通過添加日期到一個數組做到這一點,在我每次讀一個新的日期時間控制。但我正在尋求更有效的方法。有沒有一種合乎邏輯的方式來做到這一點或perl中的任何數據結構?

+0

管道輸出通過'排序-u'? –

+2

我認爲[這個問題] [1]應該可以解決你的問題。 [1]:http://stackoverflow.com/questions/7651/how-do-i-remove-duplicate-items-from-an-array-in-perl – chooban

+0

我覺得沒有辦法按照我提到的方式 – user2870

回答

2

它將逐行掃描以\d\d/\d\d/\d{4}格式查找日期,並將它們保存爲散列值作爲關鍵字。

當文件讀取完成後,它會打印這些唯一鍵。

perl -nE '$s{$_}++ for m| (\d\d/\d\d/\d{4}) |xg;}{say for sort keys %s' file 

它可以轉化爲更可讀的形式(加上一些檢查)

use strict; 
open my $fh, "<", "file" or die $!; 

my %s; 
while (my $line = <$fh>) { 

    my @dates = $line =~ m| (\d\d/\d\d/\d{4}) |xg; 

    for my $date (@dates) { 
    $s{$date} += 1; 
    } 
} 

for my $date (sort keys %s) { 

    print $date, "\n"; 
} 
+2

解釋上述答案的作用:使用正則表達式在文本中搜索以找到表單XX/XX/XXXX中的所有匹配,並在字典中增加該鍵(如果它隱含地創建它不存在)。 然後它只是打印出字典中的鍵。這與你的建議基本相同。 – Sysyphus

+2

小的術語更正:在Perl中,此答案中使用的數據類型稱爲「散列」,而不是「字典」。 –

+0

已更新,因此每個日期都在自己的行上。 –

0

如果你是開放的安裝模塊要做到這一點(我知道這似乎有點小題大做)List::MoreUtilsuniq方法。每個人都避免你的眼睛......這是星期五下午,很熱,可能時間發出聲音(-0777)啤酒:

perl -'MList::MoreUtils qw(uniq)' -0777nE '@dates = m|(\d\d/\d\d/\d{4})|xg ; @x = uniq(@dates); say "@x" ' file.txt

對不起;-)

+0

hm,這裏它尋找uniq並在每一行上打印,但它應該在讀取完成時執行這些操作。 –

+0

奇數,我正在使用5.18。看看不同的版本(''''''''''和'''List :: MoreUtils''')的行爲是否有所不同 - '''perlbrew exec'''來拯救!無論如何,你的解決方案是無模塊的,並使用蝴蝶'''} {'''所以是最好的默認;-)乾杯! –