使用perl删除基于订单列的行

时间:2015-09-09 16:44:22

标签: perl

我有一个用','分隔的表,我想订购并测试num列中是否存在num + 1的值,或者num中存在num + 2的值,或者存在num + 3字段的值在num中,或者num + 4中的值存在于num中,如果为true,则删除该行。

我的脚本是:

#!"C:\perl\bin\perl.exe"

use strict;
use warnings;

my $file_name = shift @ARGV;

die "Usage ./$1 <file_to_be_processed> > <output_file>" unless defined $file_name;

my $dic; # This is going to hold all values to be excluded.

open IN, "<", $file_name or die "Could not open $file_name $!\n";

while(<IN>) {
        chomp;
        @_ = split /,/;
        shift @_;
        map{$dic->{$_}++} @_;
}

close IN;

open IN, "<", $file_name or die "Could not open $file_name $!\n";

while(<IN>) {
        chomp;
        @_ = split /,/;
        print $_."\n" unless defined $dic->{$_[0]};
}

close IN;

有我的桌子:

num,num+1,num+2,num+3,num+4
1014,1015,1016,1017,1018
1015,1016,1017,1018,1019
1019,1020,1021,1022,1023
1025,1026,1027,1028,1029
1030,1031,1032,1033,1034

预期结果:

num,num+1,num+2,num+3,num+4
1014,1015,1016,1017,1018
1019,1020,1021,1022,1023
1025,1026,1027,1028,1029
1030,1031,1032,1033,1034

我的脚本有效但从结果中排除了数字1019,有实际脚本的输出:

num,num+1,num+2,num+3,num+4
1014,1015,1016,1017,1018
1025,1026,1027,1028,1029
1030,1031,1032,1033,1034

2 个答案:

答案 0 :(得分:1)

正在跳过1019,因为即使在第二个循环中跳过1015行,也会在第一个循环中为$dic定义1019键。

map{$dic->{$_}++} @_;

在第一个循环(1015行)的第二次迭代中,该行设置键1016,1017,1018和1019(到1)。然后在你的第二个循环中:

print $_."\n" unless defined $dic->{$_[0]};

你的unless跳过1015,但没有做任何事情来删除1015行用它定义的键,所以它继续删除1019行。

答案 1 :(得分:1)

如果我理解正确,那就是你需要的一切

use strict;
use warnings;

my %seen;

while ( <DATA> ) {
    chomp;
    my @fields = split /,/;
    if ( not $seen{ shift @fields } ) {
        $seen{$_} = 1 for @fields;
        print "$_\n";
    }
}

__DATA__
1014,1015,1016,1017,1018
1015,1016,1017,1018,1019
1019,1020,1021,1022,1023
1025,1026,1027,1028,1029
1030,1031,1032,1033,1034

输出

1014,1015,1016,1017,1018
1019,1020,1021,1022,1023
1025,1026,1027,1028,1029
1030,1031,1032,1033,1034