第一个字符串匹配后读取行的问题

时间:2019-01-08 14:57:03

标签: perl if-statement conditional

不确定该脚本为何不起作用。谁能建议一个修复程序以获得预期的输出?

Perl脚本:

open(INFILE,"test_input.txt")||die "can't open the file";   
while(<INFILE>){    
$_=~s/^\s+//;    
$_=~s/\s+$//;    
    if ($_ =~ /work/){    
        <INFILE> or die "Bad file format";    
        my $model = INFILE;    
        print "line below search: $model\n";    
        if ($model =~/^good/){    
            print "found good word\n";    
        }    
        else{    
            print "no good word\n";    
        }    
    }    
}    

输入文件:

employment  
work hard  
good people

预期输出:

line below search: good people
found good word

实际输出:

line below search:
no good word

2 个答案:

答案 0 :(得分:1)

尝试一下。 将文件读入数组。逐行处理。您可以检查当前行和下一行。

my $file = 'testFile.txt';
open my $fh, "<", "test_input.txt" or die "can't open the file"; 
chomp(my @data = <$fh>);
close $fh;

for my $index (0..$#data) { 
    if($data[$index] =~ /work/){
        my $nextIndex = $index + 1;
        die "Bad file format" unless(defined $data[$nextIndex]);
        print "line below search: $data[$nextIndex]\n";
        if ($data[$nextIndex] =~/^good/){
            print "found good word\n";
        }
        else{
            print "no good word\n";
        }
    }
}

答案 1 :(得分:1)

您非常亲密。为了使您的程序按预期运行,我只需要进行一些更改。

您有以下代码:

<INFILE> or die "Bad file format";    
my $model = INFILE;

我认为您正在尝试确保匹配的行之后实际上还有另一行。但是在这些行的第一行中,您只需读取下一行并丢弃数据即可。在第二行中,将$model设置为字符串“ INLINE”。也许您的意思是my $model = <INFILE>-但是即使您已经读(并丢弃)了上一行代码中想要的记录,也无法满足您的需求。

所以我认为您想用一行替换这两行。

my $model = <INFILE> or die "Bad file format";

如果您有兴趣,这就是我的写法。注意,我已经摆脱了硬编码的文件名。相反,我从通用文件句柄<>中读取。这将自动连接到其名称已通过命令行传递给程序的文件。这样做的好处是,代码a)易于编写(因为您不需要显式打开文件),b)更加灵活(因为您可以处理任何名称的文件)。我还删除了$_ =~的一些不必要的用法。

#!/usr/bin/perl

# Always use these
use strict;
use warnings;

use feature 'say'; # for 'say()'

while (<>) {
  s/^\s+//; # No need for $_ =~
  s/\s+$//;

  if (/work/) {
    my $model = <> or die "Bad file format";

    if ($model =~ /^good/) {
      say 'found good word';
    } else {
      say 'no good word';
    }
  }
}