Perl脚本只删除匹配的重复行?

时间:2016-04-28 08:22:00

标签: regex perl duplicates

我知道哈希可用于删除文件中的重复行,并删除文件中的所有重复行。我使用以下行删除文件中的所有重复行..

my %lines;
while (<DATA>) {
print if not $lines{$_}++;
}

但是,我只需删除匹配模式的重复行... 示例输入文件:

line1
line2
line3
line1 #duplicate line
line2 #duplicate line
line4
line5

虽然line1和line2都是重复的,但我只想删除line1的重复。

输出:

line1
line2
line3
line2 #this duplicated line need to be resumed
line4
line5

任何建议将哈希和正则表达式结合起来以实现我的要求???

3 个答案:

答案 0 :(得分:0)

my %lines;
while (<DATA>) {
    next if $lines{$_}++ and /^line2/;
    print;
}

部分/^line2/是描述某些数据/文本的正则表达式。有关详细信息,请参阅http://perldoc.perl.org/perlre.html

next行会跳过所有重复匹配的行。你可以像! /^line1/;

一样轻易否定这一点

答案 1 :(得分:0)

假设要移除的上一行是触发器,使得重复的免除被删除以及您希望忽略注释;

use v5.12;
use warnings;

my %lines;
my $previous_line_removed = 0;
while (<>) {
   my $original_line = $_ ;
   chomp ;
   s/\s*#.*?$// ;
   if ( $lines{$_}++ && ! $previous_line_removed ) {
        $previous_line_removed = 1 ;
   }
   else {
       print $original_line ;
       $previous_line_removed = 0 ;
   }
}
#
# when fed data above...
#
line1
line2
line3
line2 #duplicate line
line4
line5

答案 2 :(得分:0)

此解决方案允许您设置正则表达式模式$check_dups,该模式定义哪些行易于重复删除。如果一条线与该模式匹配,那么如果之前已经看到它就被移除;保留所有其他行

此处,根据您问题中的示例的要求,只删除与/line1/匹配的重复行

use strict;
use warnings 'all';

my $check_dups = qr/line1/;

my %seen;

while ( <DATA> ) {
    if ( /$check_dups/ ) {
        print unless $seen{$_}++;
    }
    else {
        print;
    }
}

__DATA__
line1
line2
line3
line1
line2
line4
line5

输出

line1
line2
line3
line2
line4
line5