【问题标题】:Perl - Find duplicate lines in file or arrayPerl - 在文件或数组中查找重复的行
【发布时间】:2011-05-04 13:45:32
【问题描述】:

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

【问题讨论】:

  • 很大程度上取决于输入的大小、行的大小和潜在的重复数。如果内存要求低,那么带有%duplicates 哈希的解决方案就足够了。
  • 他们是。我只是使用 文件句柄来快速检查一些东西。看起来没有任何重复,所以很好。

标签: perl line-processing


【解决方案1】:

使用标准的 Perl 速记:

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

作为“单线”:

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

更多数据?这将打印&lt;file name&gt;:&lt;line number&gt;:&lt;line&gt;:

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

%seen的解释:

  • %seen 声明一个散列。对于输入中的每个 unique 行(在这种情况下来自 while(&lt;&gt;)$seen{$_} 将在由行文本命名的哈希中具有一个标量槽(这就是 @ 987654329@ 在有 {} 大括号中做)。
  • 使用后缀自增运算符 (x++),我们获取表达式的值,记住在表达式之后自增。所以,如果我们没有“看到”$seen{$_} 行是未定义的——但是当强制进入像这样的数字“上下文”时,它会被视为 0——并且 false
  • 然后递增到 1。

所以,当while 开始运行时,所有行都是“零”(如果有帮助,您可以将这些行视为“不是%seen”)然后,我们第一次看到一行,@987654335 @ 采用未定义的值 - 使 if 失败 - 并将标量槽处的计数增加到 1。因此,对于任何未来发生的事件,它通过 if 条件并打印为 1。

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

另外一个巧妙的事情是,最后,如果您愿意使用它,您可以计算每行重复了多少次。

【讨论】:

  • 你能解释一下 $seen{$_}++ 是如何工作的吗?我知道它正在将当前行的值分配给哈希表,但是 ++ 在这里做了什么使它找到重复项?
  • $seen{$_} 引用哈希 %seen 中的一个值,键为 $_,即当前行。 ++ 运算符将增加哈希值。这意味着,第一次出现键时,它的值将是 false,并且不会发生打印。随后的时间,它将>0,因此将执行打印,并且默认情况下不带参数的打印会打印 $_ 变量。
  • 啊,所以哈希的键是行,但值是在文件中找到的次数-1。
  • perl 书呆子给我留下了深刻的印象。如果可以的话 +2!
【解决方案2】:

试试这个

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

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

【讨论】:

  • 我会做print unless exists $duplicates{$_}。并为-wuse strictuse warnings +1。
【解决方案3】:

重复打印一次:

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

【讨论】:

  • 这就像典型的 Unix shell 中的sort file.txt | uniq -d(仅打印重复项)。是否有 sort file.txt | uniq -u 的简单等效项(仅打印唯一行)?
【解决方案4】:

如果你有一个类Unix系统,你可以使用uniq:

uniq -d foo

uniq -D foo

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

【讨论】:

    猜你喜欢
    • 2011-12-18
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2021-11-24
    • 2019-02-28
    • 2016-08-15
    • 2019-01-27
    相关资源
    最近更新 更多