Perl - 在文件或数组中查找重复的行

Chr*_*ris 6 perl line-processing

我正在尝试从文件句柄中打印重复的行,而不是删除它们或我在其他问题上看到的任何其他内容.我没有足够的perl经验能够快速做到这一点,所以我在这里问.这样做的方法是什么?

Axe*_*man 23

使用标准Perl shorthands:

my %seen;
while ( <> ) { 
    print if $seen{$_}++;
}
Run Code Online (Sandbox Code Playgroud)

作为"一线":

perl -ne 'print if $seen{$_}++'
Run Code Online (Sandbox Code Playgroud)

更多数据?这打印<file name>:<line number>:<line>:

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

说明%seen:

  • %seen声明一个哈希.对于输入中的每个唯一行(while(<>)在这种情况下来自),$seen{$_}将在该行的文本中指定的散列中有一个标量槽(这是$_在有{}大括号中所做的).
  • 使用postfix increment operator(x++),我们获取表达式的值,记住在表达式之后递增它.因此,如果我们没有"看到"该行$seen{$_}是未定义的 - 但是当强制进入这样的数字"上下文"时,它被视为0 - 而且为.
  • 然后它增加到1.

因此,当while开始运行时,所有行都为"零"(如果它可以帮助您将这些行视为"不%seen")那么,我们第一次看到一条线时,perl会取出未定义的值 - 这会使if- 并且会增加标量槽的计数为1.因此,对于将来通过if条件并打印的任何未来事件,它为1 .

现在,如上所述,%seen声明一个哈希,但strict关闭后,可以在现场创建任何变量表达式.所以perl第一次看到$seen{$_}它知道我正在寻找%seen,它没有它,所以它创造了它.

关于这一点的一个额外的好处是,最后,如果你想使用它,你有一个重复每一行的次数.