我在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, $_);
}
}
答案 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