1

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

#!/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;

ps - 我知道我可以使用,但是,我认为在这种情况下使用 'Tie::File` 会更直接一点。

4

1 回答 1

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 倍!

于 2013-02-12T20:35:47.850 回答