0

タイムスタンプが一致する場合、現在の行に次の行を追加する方法を見つけるのに苦労しています。これまでの私のコードは次のとおりです。

open(FH, "error_log:);
@data = <FH>
foreach $line (@data) {
        if ( ($line =~ /notice/)) {  
                $line =~ s/ /,/g;    
                my @L1 = split(/|notice|\[|\]|,mpmstats:,|\t|rdy,|bsy,
+|rd,|wr,|ka,|log,|dns,|cls,|bsy:,|in,|/, $line);
                $line =~ s/|notice|\[|\]|,mpmstats:,|\t|rdy,|bsy,|rd,|
+wr,|ka,|log,|dns,|cls,|bsy:,|in,//g;                    
                print $line;

出力を見るためだけに印刷したことに注意してください。出力は次のとおりです。

Wed,Jun,13,10:40:35,2012,758,42,0,29,11,0,0,2
Wed,Jun,13,10:40:35,2012,29,mod_was_ap22_http.c
Wed,Jun,13,10:41:35,2012,761,39,0,34,5,0,0,0
Wed,Jun,13,10:41:35,2012,34,mod_was_ap22_http.c
Wed,Jun,13,10:42:35,2012,769,31,0,22,6,0,0,3
Wed,Jun,13,10:42:35,2012,22,mod_was_ap22_http.c
Wed,Jun,13,10:43:35,2012,754,46,0,29,17,0,0,0

タイムスタンプに対応する最初の行の数字 (2 行目の 29) を csv 形式で配置したいと思います。残りの行は削除できます。行の下に何もない場合 (最後の行など)、ゼロを追加したいと思います。ご協力ありがとうございました。

以下は、要求された入力データの一部です。

[Wed Jun 13 01:41:24 2012    [error  [client 10.119.84.9     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:25 2012    [error  [client 10.119.84.9     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:25 2012    [error  [client 10.119.84.8     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:28 2012    [error  [client 10.119.116.8    File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:28 2012    [error  [client 10.119.84.8     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:34 2012    [notice     mpmstats: rdy 786 bsy 14 rd 0 wr 11 ka 3 log 0 dns 0 cls 0 
[Wed Jun 13 01:41:34 2012    [notice     mpmstats: bsy: 11 in mod_was_ap22_http.c   
[Wed Jun 13 01:41:34 2012    [error  [client 10.119.84.9     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
[Wed Jun 13 01:41:35 2012    [error  [client 10.119.84.9     File does not exist: /ebiz/b2b/IHS70prd/htdocs/offline.b2bonline.html
4

2 に答える 2

1

あなたの入力は非常に奇妙です。通常、一致する角括弧が表示されます。

それはさておき、あなたが望むのは次のようなものです:

# This assumes you have Perl 5.10 or autodie installed: failures in open, readline, 
# or close will die automatically
use autodie;

# chunks of your input to ignore, see below...
my %ignorables = map { $_ => 1 } qw(
    [notice mpmstats: rdy bsy rd wr ka log dns cls bsy: in
);

# 3-arg open is safer than 2, lexical my $fh better than a global FH glob
open my $error_fh, '<', 'error_log'; 

# Iterates over the lines in the file, putting each into $_
while (<$error_fh>) {

    # Only worry about the lines containing [notice
    if (/\[notice/) {

        # Split the line into fields, separated by spaces, skip the %ignorables
        my @line = grep { not defined $ignorables{$_} } split /\s+/;

        # More cleanup
        s/^\[//g for @line; # remove [ from [foo

        # Output the line
        print join(",", @line);

        # Assuming the second line always has "in" in it, 
        # but this could be whatever condition that fits your data...
        if (/\bin\b/) {  # \b matches word edges, e.g., avoids matching "glint"
            print "\n";
        }
        else {
            print ",";
        }
    }
}

close $error_fh;

私はこれをコンパイルしていないので、どこかにタイプミスがないことを保証することはできません.

ここで重要なのは、最初printは改行なしで行い、カンマで終了することです。次に、これが 2 行目であることを検出したら、改行を追加します。

代わりに、ループの外側で宣言@lineし、それを使用して、最後に改行を付けて出力する必要があるまでフィールドを蓄積することができます。

于 2012-07-02T19:02:42.497 に答える
0

を使用した片道perl[noticeを含まない行は省略します。一致する行ごとに、変数がインクリメントされ、奇数か偶数か (最初の[通知または 2 番目の通知)に応じて、配列に異なるフィールドが保存されます。

perl -ane '
    next unless $F[5] eq q|[notice|;
    ++$notice;
    if ( $notice % 2 != 0 ) {
        push @data, @F[0..4, 8, 10, 12, 14, 16, 18, 20, 22];
        next unless eof;
    }

    push @data, (eof) ? 0 : $F[8];
    $data[0] =~ s/\A\[//;
    printf qq|%s\n|, join q|,|, @data;
    @data = ();
' infile

質問の内容があると仮定するとinfile、出力は次のようになります。

Wed,Jun,13,01:41:34,2012,786,14,0,11,3,0,0,0,11
于 2012-07-02T19:03:49.453 に答える