使用特定字符串选择特定行

时间:2015-08-12 12:52:44

标签: perl

我在Perl中尝试从整个文档中选择一个完整的行,其中包含" CURRENT_RUN_ID"。我一直在使用下面的代码来完成上述任务,但我无法进入while循环。

my $sSuccessString = "CURRENT_RUN_ID";

open(LOG, "$slogfile") or die("Can't open $slogfile\n");
my $sLines;
{
    local $/ = undef;
    $sLines=<LOG>;
}
my $spool = 0;
my @matchingLines;

while (<LOG>) 
{
    print OUTLOG "in while loop\n";

    if (m/$sSuccessString/i) {
        print OUTLOG "in if loop\n";
        $spool = 1;
        print map { "$_ \n" } @matchingLines;
        @matchingLines = ();
    }
    if ($spool) {
        push (@matchingLines, $_);
    }
}

2 个答案:

答案 0 :(得分:4)

在您将文件句柄LOG投入使用后,您已经完成了文件句柄$sLines的阅读。 <LOG>头部的while将返回undef,因为它已达到eof。您必须在$sLines循环中使用该变量while或删除它。你还是不用它。

如果您只想打印匹配的行,您只需要这样做:

use strict;
use warnings;

open my $fh_in, '<', 'input_file' or die $!;
open my $fh_out '>', 'output_file' or die $!;

while (my $line = <$fh_in>) {
  print $fh_out $line if $line =~ m/CURRENT_RUN_ID/;
}

close $fh_in;
close $fh_out;

答案 1 :(得分:1)

执行此代码时:

$sLines=<LOG>;

它将LOG中的所有数据读入$sLines,并在文件末尾留下LOG的文件指针。所以下次尝试从该文件句柄中读取:

while (<LOG>)

没有返回任何内容,因为没有更多数据可供阅读。

如果要读取文件两次,则需要使用seek()函数在第二次读取之前重置文件指针。

seek LOG, 0, 0;

但是,鉴于你从未对$sLines做任何事情,我怀疑你可能只是删除整段代码。

$spool@matchingLines的全部内容似乎也很奇怪。你想在那里实现什么目标?

我认为您的代码可以简化为:

my $sSuccessString = "CURRENT_RUN_ID";

open(LOG, $slogfile) or die("Can't open $slogfile\n");

while (<LOG>) {
    print OUTLOG if /$sSuccessString/i/;
}

就个人而言,我通过阅读STDIN并写入STDOUT来使其更简单。

my $sSuccessString = 'CURRENT_RUN_ID';

while (<>) {
    print if /$sSuccessString/i/;
}

然后使用Unix I / O重定向连接正确的文件。

$ ./this_filter.pl < your_input.log > your_output.log