2011-12-31 75 views
1

我想從文件中獲取重複行的最後一個條目。
重複檢查的基礎將是csv的第一個元素。如何使用perl從文件中獲取最後一個重複行

副本可能相鄰,也可能不相鄰。

輸入文件:

971~11 
972~12 
973~11 
974~11 
972~11 

預期輸出:

971~11 
973~11 
974~11 
972~11 

我不是在尋找一個Perl的一個班輪,我打算寫爲
的子程序。

謝謝!

PS:
我從什麼地方修改這個代碼,但是這只是刪除了重複

#!/usr/bin/perl -w 

while (<STDIN>) { push (@lines, $_); } 

print "-\n"; 

foreach my $i (@lines) 
{ 
    @newline = split(/\||~/, $i); 

    if (scalar(grep{ /$newline[0]/ } @lines) == 1) 
    { 
     print $i; 
    } 
} 
+1

是輸出的重要順序? – Mat 2011-12-31 14:50:20

+0

輸入必須讀取未排序,但輸出順序無關緊要。 – cr8ivecodesmith 2011-12-31 14:58:22

+1

請解釋一下這個更多?你想要「獲得」最後一個重複條目。 (你的意思是刪除它或捕獲它?)通過重複輸入,你真的意味着只複製第一個字段?根據您提供的輸出,我懷疑您所要保留的是最後一次出現具有重複第一個字段的條目,並刪除先前看到的任何條目。 – lhagemann 2011-12-31 15:02:37

回答

4

如果輸出順序並不重要,要做到這一點最簡單的方法是使用散列做重複刪除。類似以下內容:

#!/usr/bin/perl -w 
use strict; 

sub printlast(@) { 
    my %dedup; 
    foreach my $line (@_) { 
     my $a = (split(/\||~/, $line))[0]; 
     $dedup{$a} = $line; 
    } 
    print $dedup{$_} for keys %dedup; # or sort keys %dedup for prettier output 
} 

my @lines; 
while (<STDIN>) { push (@lines, $_); } 

print "-\n"; 

printlast(@lines); 
+0

非常感謝!其實我的確說過我不想要單行:) – cr8ivecodesmith 2011-12-31 15:15:40

+0

祝你新年快樂! – cr8ivecodesmith 2011-12-31 15:15:49

+0

祝你新年快樂:)(我完全誤讀了你的問題中的單行部分,對此很抱歉。) – Mat 2011-12-31 15:24:46

1

當想要進行重複數據刪除時,幾乎總是使用散列最好。

這裏是類似於接受的答案的東西(因爲@Mat打我吧)

#!/usr/bin/env perl -lw 

use Data::Dumper; $Data::Dumper::Indent = 1; 

my %seen; 
while (<DATA>) { 
    chomp; 
    my @fields = split('~'); 
    $seen{$fields[0]} = $fields[1]; 
} 

my @output; 
while (my ($k,$v) = each %seen) { 
    push @output, join('~', $k, $v); 
} 

print Dumper \@output; 

__DATA__ 
971~11 
972~12 
973~11 
974~11 
972~11 
相關問題