如何使用perl脚本删除重复行

问题描述 投票:0回答:4

如何删除重复行?

我当前的代码:

use strict;
use warnings;
my $input = input.txt;
my $output = output.txt;
my %seen;

open("OP",">$output") or die;
open("IP","<$input") or die;

while(my $string = <IP>) {
    my @arr1 = join("",$string);
    my @arr2 = grep { !$seen{$_}++ } @arr1;
    print "@arr2\n";
    print OP "@arr2\n";
}

close("IP");
close("OP");

输入:

india
australia
america
singapore
india
america

预期输出:

india
australia
america
singapore
perl duplicates
4个回答
4
投票

使用此 Perl 一行代码删除所有重复项,无论是否相邻:

perl -ne 'print unless $seen{$_}++;' input.txt > output.txt

仅删除相邻重复项(如 UNIX

uniq
命令):

perl -ne 'print unless $_ eq $prev; $prev = $_; ' input.txt > output.txt

Perl 一行代码使用这些命令行标志:

-e
:告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,默认将其分配给
$_

当第一次看到该行时,首先评估

$seen{$_}
,并且为 false,因此打印该行。然后,
$seen{$_}
加一,这使得每次再次看到该行时都为真(因此不再打印同一行)。

第一个单行避免一次将整个文件读入内存,这对于具有大量长重复行的输入可能很重要。仅将每行的第一次出现及其出现次数存储在内存中。

另请参阅:


2
投票

请研究以下代码片段,您已经非常接近利用

%seen
哈希了。

use strict;
use warnings;
use feature 'say';

my %seen;
my @uniq;

while( <DATA> ) {
    chomp;
    push @uniq, $_ unless $seen{$_};
    $seen{$_} = 1;
}

say for @uniq;

__DATA__
india
australia
america
singapore
india
america

输出

india
australia
america
singapore

2
投票

从脚本中删除了不需要的代码行。

这是更新后的脚本:

use strict; use warnings;
use Data::Dumper;

my %seen;

my @lines = <DATA>;
chomp @lines;

my @contries = grep { !$seen{$_}++ } @lines;
print Dumper(\@contries);

__DATA__
india
australia
america
singapore
india
america

结果:

$VAR1 = [
          'india',
          'australia',
          'america',
          'singapore'
        ];

1
投票

你把这一切搞得太复杂了。代码的主要部分可以简化为:

while (<IP>) {
  print unless $seen{$_}++;
}

甚至:

print grep { ! $seen{$_}++ } <IP>;
© www.soinside.com 2019 - 2024. All rights reserved.