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