Как получить последнюю дублирующую строку из файла, используя perl - PullRequest
1 голос
/ 31 декабря 2011

Я хотел бы получить последнюю запись дублирующейся строки из файла.
Основой для проверки дубликатов будет первый элемент из CSV.

Дубликаты могут быть или не быть смежными.

Входной файл:

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;
    }
}

Ответы [ 2 ]

4 голосов
/ 31 декабря 2011

Если порядок вывода не имеет значения, самый простой способ сделать это - использовать хеш для удаления дубликатов.Примерно так:

#!/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);
1 голос
/ 31 декабря 2011

При поиске дедупликации почти всегда лучше использовать хеш.

Вот что-то похожее на принятый ответ (так как @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...