我正在尝试从文件句柄中打印重复的行,而不是删除它们或我在其他问题上看到的任何其他问题。我没有足够的 perl 经验来快速做到这一点,所以我在这里问。这样做的方法是什么?
问问题
19243 次
4 回答
25
使用标准的 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
”)然后,当我们第一次看到一行时,perl
将采用未定义的值 - 它失败了if
- 并递增标量槽的计数为 1。因此,对于任何未来发生的事件,它都为 1,此时它通过if
条件并打印。
现在就像我上面所说的,%seen
声明一个哈希,但是strict
关闭后,可以在现场创建任何变量表达式。所以 perl 第一次看到$seen{$_}
它就知道我正在寻找%seen
,它没有它,所以它创建了它。
一个额外的整洁的事情是,最后,如果你愿意使用它,你可以计算每行重复了多少次。
于 2011-05-04T13:50:26.517 回答
3
只打印一次副本:
perl -ne "print if $seen{$_}++ == 1"
于 2011-11-02T20:08:01.643 回答
3
尝试这个
#!/usr/bin/perl -w
use strict;
use warnings;
my %duplicates;
while (<DATA>) {
print if !defined $duplicates{$_};
$duplicates{$_}++;
}
于 2011-05-04T13:50:32.160 回答
1
于 2011-05-04T16:07:37.963 回答