如何在 Perl 中查看文件的下一行

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

我有一段代码可以打开一个文件并解析它。该文本文档具有冗余结构并且具有多个条目。我需要在循环中向前查看是否有新条目,如果有,我将能够解析程序提取的所有数据。让我首先展示到目前为止我的实现

use strict;
my $doc = open(my $fileHandler, "<", "test.txt");

while(my $line = <$fileHandler>) {
    ## right here I want to look at the next line to see if 
    ## $line =~ m/>/ where > denotes a new entry
}
perl parsing search peek
3个回答
9
投票

尝试自己处理迭代:

my $line = <$fileHandler>;
while(1) { # keep looping until I say so
    my $nextLine = <$fileHandler>;

    if ($line =~ m/>/ || !defined $nextLine) {
        ### Do the stuff
    }
    ### Do any other stuff;

    last unless defined $nextLine;
    $line = $nextLine;
}

我在 if 语句中添加了额外的检查,假设您还想在到达文件末尾时处理您所拥有的内容。

或者,按照 Friedo 的建议,如果文件可以放入内存,您可以立即将整个文件加载到数组中:

my @lines = <$fileHandler>;
for (my $i = 0; $i <= $#lines; $i++) {
    if ($i == $#lines || $lines[$i+1] =~ />/) {
        ### Do the stuff
    }
}

这更灵活,因为您可以按任何顺序访问文件的任意行,但正如前面提到的,文件必须足够小才能适合内存。


5
投票

处理这些问题的一个好方法是使用

Tie::File
,它允许您将文件视为数组,而不会因实际将文件加载到内存中而造成性能损失。它也是从 perl v5.7.3 开始的核心模块。

use Tie::File;
tie my @file, 'Tie::File', "test.txt" or die $!;

for my $linenr (0 .. $#file) {             # loop over line numbers
    if ($file[$linenr] =~ /foo/) {         # this is the current line
        if ($file[$linenr + 1] =~ /^>/ &&  # this is the next line
            $linenr <= $#file) {           # don't go past end of file
             # do stuff
        }
    }
}
untie @file;   # all done

0
投票

我只是为了正义而使用了 #5 中的 Tie::File 代码。我的文件有一个主机名,下一行是主机名或主机的暴击级别。如果存在暴击级别,我会用主机名和暴击创建一行以输出到 CSV;如果没有指定暴击,我就指定为0。

(我必须拆分行,因为该行是 name:servername 或 critlevel:99,并清理前导/尾随空格)

for my $linenumber (0..$#file) {
        #print "$file[$linenumber]\n";
        if ($file[$linenumber] =~/name/) {
                ($crap,$server) = split(/\:/,$file[$linenumber],2);
                $server =~ s/^\s+|\s+$//g; 
                #print "$server\n";
                if ($file[$linenumber+1] =~/server/ && $linenumber <=$#file) { 
                        ($crap,$crit) = split(/\:/,$file[$linenumber+1],2);
                        $crit =~ s/^\s+|\s+$//g;
                        #print "$crit\n";
                }
                else { $crit = "0"; }
        $outstr = "$server,$crit\n";
        print $outstr;
        print OUTFILE $outstr;
        
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.