如何找到以" PASS"结尾的最后一行?在我的文本文件中?

时间:2014-03-13 16:00:59

标签: regex perl

我有一个看起来像这样的文本文件:

--------- Voltage = 1.150000 V --------->PASS




--------- Voltage = 1.140000 V --------->PASS




--------- Voltage = 1.130000 V --------->PASS




--------- Voltage = 1.120000 V --------->PASS




--------- Voltage = 1.110000 V --------->PASS




--------- Voltage = 1.100000 V --------->PASS




--------- Voltage = 1.090000 V --------->FAIL

我想检索最后一个传递值,在本例中为1.100000V。我怎么能用正则表达式做到这一点?我尝试了以下但是没有给出正确的答案:

open(my $FH, $FileName) or die "$!\n";

while($line = <$FH>)
{
    if($line =~ /FAIL/)
    {
        if($line =~ m/^\d*\.?\d*/) #check for the decimal number? not sure
        {
            print $&;   # I intend to print the matched number here?
        }
    }
}

3 个答案:

答案 0 :(得分:1)

由于^,您在字符串的开头寻找一个数字。当然,那里没有一个。您可以使用/(\d+(?:\.\d+))/提取数字,但为什么不采用Voltage =后面的内容?

你说你想要最后通过的电压,但你试图捕获失败的电压!

避免使用$&因为它会减慢每次匹配和替换而不会捕获。

open(my $FH, $FileName)
   or die "$!\n";

my $passing_voltage;
while ($line = <$FH>) {
   if (my ($voltage) = $line =~ /Voltage = (\S+)/) {
      last if $line =~ /FAIL/;
      $passing_voltage = $voltage;
   }
}

die("No passing voltage\n") if !defined($passing_voltage);
print("$passing_voltage\n");

无需触摸$/


以上内容非常简单,但通过从头到尾阅读文件可以进一步简化。

use File::ReadBackwards qw( );

my $fh = File::ReadBackwards->new($FileName)
   or die("$!\n");

my $voltage;
while ( defined( my $line = $fh->readline() ) ) {
   if ($line =~ /Voltage = (\S+).*PASS/) {
      $voltage = $1;
      last;
   }
}

die("No passing voltage\n") if !defined($voltage);
print("$voltage\n");

答案 1 :(得分:1)

这将读取整个文件,然后打印匹配的最后一行的数字。

while (<>)
{
    # last if m/FAIL$/;  # see below
    next unless m/(\d+\.\d) V/;  # Capture number in $1
    $keep = $1 if m/PASS$/;
}
print $keep;

要进行优化,如果您知道第一个FAIL不会被任何PASS es跟踪,请取消注释last行。

作为单行,

perl -ne 'next unless m/(\d+\.\d+) V .*PASS$/; $k = $1; END { print $k }' filename

答案 2 :(得分:-2)

嗯,嗯。

open(my $FH, $FileName) or die "$!\n";
# suggested change for poster is 
# open (FH, $fileName) } or die "found not open file $1\n";
$lastPass = "init"; # in the event of a fail on first line.

while($line = <FH>){
   next if $line =~ /^$/;  # if no string data why even bother
   if($line =~ /FAIL/i){   # look for a fail 
      print "fail detected  $line \n";  #print a warning
      last;        # exit the loop
   }
   else {
    if ($line =~ m/(\d*\.?\d*)/) {  # if the line is not a fail record
       $lastPass = $line;
       $voltage = $1;  # voltage if you want it in the $1 regex memory
    }       
  }

}
# close (FH);  # suggestion
if ($lastPass eq "init") {   # did we find a fail before a pass.
  print "detected fail before good data \n";
}
else {
  print $lastPass, "\n";
  print $voltage , "\n";
}