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

时间:2011-05-04 13:45:32

标签: perl line-processing

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

4 个答案:

答案 0 :(得分:23)

使用标准的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{$_}将在行的文本命名的哈希中有一个标量槽(这是$_{}括号中所做的事情。
  • 使用后缀增量运算符(x++),我们获取表达式的值,记住在表达式之后递增它。所以,如果我们没有“看到”,那么行$seen{$_}是未定义的 - 但是当强制进入这样的数字“上下文”时,它被视为0 - 而 false
  • 然后它增加到1.

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

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

关于这一点的一个更加巧妙的事情是,最后,如果你想使用它,你可以计算每一行重复的次数。

答案 1 :(得分:3)

试试这个

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

my %duplicates;
while (<DATA>) {
    print if !defined $duplicates{$_};
    $duplicates{$_}++;
}

答案 2 :(得分:3)

只打印一次dupes:

perl -ne "print if $seen{$_}++ == 1"

答案 3 :(得分:0)

如果您有类Unix系统,可以使用uniq

uniq -d foo

uniq -D foo

应该做你想做的事。更多信息:man uniq