Perl - найти повторяющиеся строки в файле или массиве - PullRequest
6 голосов
/ 04 мая 2011

Я пытаюсь напечатать дубликаты строк из файлового дескриптора, а не удалять их или что-либо еще, что я вижу, задаваемые по другим вопросам.У меня недостаточно опыта работы с Perl, чтобы быстро это сделать, поэтому я спрашиваю здесь.Как это сделать?

Ответы [ 4 ]

23 голосов
/ 04 мая 2011

Использование стандартных сокращений Perl:

my %seen;
while ( <> ) { 
    print if $seen{$_}++;
}

В качестве «однострочного»:

perl -ne 'print if $seen{$_}++'

Больше данных?Это печатает <file name>:<line number>:<line>:

perl -ne 'print ( $ARGV eq "-" ? "" : "$ARGV:" ), "$.:$_" if $seen{$_}++'

Объяснение %seen:

  • %seen объявляет хэш.Для каждой уникальной строки на входе (которая в данном случае идет от while(<>)) $seen{$_} будет иметь скалярную ячейку в хэше, названную текстом строки (это то, что $_ делает в 10 * фигурных скобках).
  • Используя оператор приращения постфикса (x++), мы принимаем значение для нашего выражения, помня увеличивать после выражения.Итак, если мы не «увидели» строку $seen{$_}, то она не определена, но когда она помещена в числовой «контекст», подобный этому, она принимается за 0 - и false .
  • Затем он увеличивается до 1.

Итак, когда while начинает работать, все строки равны "нулю" (если это поможет, вы можете думать о строках как "не %seen "), тогда, когда мы в первый раз видим строку, perl принимает неопределенное значение - что не соответствует if - и увеличивает счетчик в скалярном интервале до 1. Таким образом, это 1 для любого будущегоэкземпляры, в которых он проходит условие if и печатается.

Теперь, как я сказал выше, %seen объявляет хэш, но с отключенным strict любое переменное выражение может быть создано на месте.Поэтому в первый раз, когда Perl видит $seen{$_}, он знает, что я ищу %seen, у него его нет, поэтому он его создает.

Еще одна полезная вещь в том, что в конце, если вы захотите его использовать, у вас будет счетчик того, сколько раз каждая строка повторялась.

3 голосов
/ 03 ноября 2011

Печатает дубликаты только один раз:

perl -ne "print if $seen{$_}++ == 1"
3 голосов
/ 04 мая 2011

попробуйте

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

my %duplicates;
while (<DATA>) {
    print if !defined $duplicates{$_};
    $duplicates{$_}++;
}
0 голосов
/ 04 мая 2011

Если у вас Unix-подобная система, вы можете использовать uniq:

uniq -d foo

или

uniq -D foo

должен делать то, что вы хотите. Дополнительная информация: man uniq .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...