2011-12-31 34 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 
相关问题