2

I am interesting to grab 10 lines before it match the regex "critical" or "error" . currently I am printing $_ which gives me only the line of the regex match.

I Worte in perl the following:

#!/usr/bin/perl -w
use strict;
open LOG, "/Users/erangross/Projects/perl/log" or die;

while (<LOG>){
    if (/critical | error/){
        open (myFile, '>>parser_log.txt');
        print myFile $_;
    }


}
4

3 に答える 3

4

それはperlでなければなりませんか?GNUgrepでは、一致する行の前後に指定された行数の「コンテキスト」を印刷するオプションが提供されます。

grep --before-context=10 '(critical \| error)' parserlog.txt
于 2012-07-14T15:04:09.747 に答える
3

を使用しTie::Fileます。これは Perl v5.7.3 以降のコア モジュールであるため、インストールする必要はありません。

Tie::File配列要素であるかのように、ファイル内のレコードにランダムにアクセスできます。問題は、一致する配列のインデックスを追跡し、9 未満のインデックスからすべての要素を出力するだけです。

use strict;
use warnings;

use Tie::File;

open my $plog, '>', 'parser_log.txt' or die $!;
tie my @log, 'Tie::File', '/Users/erangross/Projects/perl/log' or die $!;

for my $i (0 .. $#log) {
  next unless / critical | error /xi;
  my $start = $i > 9 ? $i - 9 : 0;
  print $plog $log[$_] for $start .. $i;
}
于 2012-07-14T16:05:59.830 に答える
2

配列を使用します。彼らは助けることができます。ここでは、一種の FIFO またはキューとして使用します。

#!/usr/bin/perl
use warnings;
use strict;

open LOG, "<", "/Users/erangross/Projects/perl/log" or die "Can't open log: $!";
open my $parseLog, '>>', 'parser_log.txt') or die "Can't open output file: $!";

my @lastTenLines;

while (<LOG>){
    push @lastTenLines, $_; # add current line.
    shift @lastTenLines while @lastTenLines > 10; # remove lines outside your scope.
    print $parseLog @lastTenLines if /critical | error/x; # print if there is a find.
}
于 2012-07-14T15:10:54.813 に答える