perl Tie :: File删除文本文件中的行

时间:2013-02-12 20:05:22

标签: perl

我有以下代码从我正在使用的文本文件中删除行。但是,它实际上并没有删除我想要的行。我在这里做了很多测试,并确认如果我得到正确的行号,它将删除行。但是,$.似乎重复了实际的行号(就像我在它上面打印时一样,它表示实际上有两倍的行数!)

#!/usr/bin/perl
# find_company_codes.pl

use strict;
use warnings;
use diagnostics;

use Tie::File;

my $split_file = "//server/folder/splits_table.txt";

# remove fields where only MAS has rollcall
my @file;
my @lines;

tie @file, 'Tie::File', $split_file or die $_;

foreach (@file) {

    @lines = split(",",$_);

    next if $lines[0] eq "ESDB Link Processing Reg-Prd-CCD";
    next if $lines[2] ne "";
    next if $lines[3] ne "";
    next if $lines[4] ne "";
    next if $lines[5] ne "";
    next if $lines[6] ne "";

    splice(@file, $.,1);

}

untie @file;

P.S。 - 我知道我可以使用this,但是,在这种情况下,我认为使用'Tie :: File`会更加直截了当。

1 个答案:

答案 0 :(得分:2)

你不是从文件中读取,而是在迭代数组。 $.毫无意义。首先,我们需要切换到索引。

for (0..$#file) {
    my @fields = split(/,/, $file[$_]);

    next if $fields[0] eq "ESDB Link Processing Reg-Prd-CCD";
    next if $fields[2] ne "";
    next if $fields[3] ne "";
    next if $fields[4] ne "";
    next if $fields[5] ne "";
    next if $fields[6] ne "";

    splice(@file, $_, 1);
}

除此之外也不起作用。当你拼接时,你移动整个数组,所以你不能推进转向的索引,你需要尽快完成一个索引的循环。修正:

my $i = 0;
while ($i < $#file) {
    my @fields = split(/,/, $file[$i]);

    if (   $fields[0] ne "ESDB Link Processing Reg-Prd-CCD"
        && $fields[2] eq ""
        && $fields[3] eq ""
        && $fields[4] eq ""
        && $fields[5] eq ""
        && $fields[6] eq ""
    ) {
        splice(@file, $i, 1);
    } else {
        ++$i;
    }
}

好,这有效,但它很疯狂。每个splice都可以导致文件的其余部分被读取和重写。还有一个不恰当的用法:Tie :: File!以下将会非常快。

use strict;
use warnings;

my $qfn = "//rosefs19w/sal...";

my @file;
{
    open(my $fh, '<', $qfn)
        or die("Can't open $qfn: $!\n");
    @file = <$fh>;
}

my $i = 0;
while ($i < $#file) {
    my @fields = split(/,/, $file[$i]);

    if (   $fields[0] ne "ESDB Link Processing Reg-Prd-CCD"
        && $fields[2] eq ""
        && $fields[3] eq ""
        && $fields[4] eq ""
        && $fields[5] eq ""
        && $fields[6] eq ""
    ) {
        splice(@file, $i, 1);
    } else {
        ++$i;
    }
}

{
    open(my $fh, '>', $qfn)
        or die("Can't create $qfn: $!\n");
    print $fh @file;
}

没错。添加3行额外代码并删除2,代码变为100,1000,10000倍!