2016-06-25 4 views
0

こんにちは私はファイル内に複数の行を持ち、それらからユーザ名と彼が使用しているバージョンを取得できるようにしたいと考えています。Perl:ファイル検索の正規表現複数の情報を複数の行に入力する

ファイル

<W>2016-06-25 00:27:30.577 1 => <4:(-1)> Client version 1.2.10 (Win: 1.2.10) 
<W>2016-06-25 00:27:30.635 1 => <4:[AAA] User1(1850)> Authenticated 
<W>2016-06-25 00:27:30.635 1 => <2:(-1)> Client version 1.2.16 (Win: 1.2.16) 
<W>2016-06-25 00:27:30.687 1 => <2:[AAA] User2(942)> Authenticated 

Outpoutだから1つのクライアントの件のデータが2行にある

4 : User1 : 1.2.10 
2 : User2 : 1.2.16 

を望んでいました。

  • 最初の行にバージョン番号が表示されます。
  • 2行目はユーザー名です。
  • 私の例では、両方の行に一致IDがあることに気付きました。私の例では、user1行の一致IDは4:2で、2番目のユーザーは2です。

    私はこのようなことから始めましたが、実際に意図したとおりに動作せず、ファイル全体の2行目を見つけるために2番目の読み込みを作成すると、あまりにも多くの/最適化されていません。

    のPerlスクリプト

    #!/usr/bin/perl 
    use strict; 
    use warnings; 
    my $file = 'mylogfile.log'; 
    open (my $fl, '<:encoding(UTF-8)', $file) 
         or die 'File not found'; 
    
    while (my $row = <$fl>) { 
         if ($row =~ m/\<(\d+).*\>\sclient\sversion\s(\d+.\d+.\d+)\s/i) { 
           my $id = $1; 
           my $vers = $2; 
           while (my $row1 = <$fl>) { 
             if ($row1 =~ m/\<$id\:(.+)\(\d+\)\>/i) { 
               my $name = $1; 
               print "$id : $name : $vers\n"; 
             } 
           } 
         } 
    } 
    

    任意のPerlの第一人者がアイデアを持っている場合は、ありがとう! :-)

    +0

    また、phpでは、すべての検索を1行に変換するだけで簡単にできます。 s regex修飾子は良い正規表現と共に使用できます。しかし、perlはPHPで使用できるpreg_match_allとして動作しません:-( – flop

    答えて

    0

    私はperlのについて多くを知らないが、いくつかのアイデアを提供することができます:あなたのコードを実行する

    login= map(); 
    while(row=readrow()) 
    { 
        if(match(id version)) 
        login[$1]=$2 
        else 
        if(match(id username userid)) 
        { 
        print "user: ", $2, "version:",login[$1], "userid: $3", "sessionid: ", $1 
        delete login[$1] 
        } 
    } 
    
    0

    くれ

    4 : [AAA] User1 : 1.2.10 
    

    あなたの2番目の正規表現は、キャプチャされた結果を与えました括弧付きの文字のユーザー名。これはあなたの望む出力がどのように見えるかではありません。

    2番目のwhileループは、残りのファイルを使い果たします。そして、これはあなたがしたいことではありません。

    ここでは、必要な出力を生成するプログラムがあります。 (私はプログラムの先頭にファイルを作成しましたが、あなたはこれを使用せずに、あなたのコードのようにファイル 'mylogfile.log'を開きます)。私の2番目の正規表現、作品、[^(]+

    #!/usr/bin/perl 
    use strict; 
    use warnings; 
    
    open my $fh, '<', \<<EOF; 
    <W>2016-06-25 00:27:30.577 1 => <4:(-1)> Client version 1.2.10 (Win: 1.2.10) 
    <W>2016-06-25 00:27:30.635 1 => <4:[AAA] User1(1850)> Authenticated 
    <W>2016-06-25 00:27:30.635 1 => <2:(-1)> Client version 1.2.16 (Win: 1.2.16) 
    <W>2016-06-25 00:27:30.687 1 => <2:[AAA] User2(942)> Authenticated 
    EOF 
    
    
    while (<$fh>) { 
        if (/<(\d+).+?Client version (\d+\.\d+\.\d+)/) { 
         my ($id, $vers) = ($1, $2); 
    
         # read next line and capture name 
         if (<$fh> =~ /<$id\S+ ([^(]+)/) { 
          my $name = $1; 
          print join(" : ", $id, $name, $vers), "\n"; 
         } 
        } 
    } 
    

    否定クラスと呼ばれています。それは非 '左括弧'(1回以上)と一致します。これは、ファイルの行に 『「ユーザー1' と』ユーザー2と一致する

    更新:。。あなたは文字クラスhereについての情報を見つけることができます

    アップデート2: wolfrevokcats回答を見ると、私は彼が作っ見ます有効な観察と彼の解決策はより安全です。

    1

    対応する行のタイムスタンプが異なることがログファイルに記録されています。 だから、私は、例えば、散在得ることができ、レコードをログに記録し、2人のユーザーが同時にログインするとき、とします

    <W>2016-06-25 00:27:30.577 1 => <4:(-1)> Client version 1.2.10 (Win: 1.2.10) 
    <W>2016-06-25 00:27:30.635 1 => <2:(-1)> Client version 1.2.16 (Win: 1.2.16) 
    <W>2016-06-25 00:27:30.635 1 => <4:[AAA] User1(1850)> Authenticated 
    <W>2016-06-25 00:27:30.687 1 => <2:[AAA] User2(942)> Authenticated 
    

    このような場合は、私はidを覚えているハッシュを使用することをお勧めします:

    use strict; 
    use warnings; 
    my $file = 'mylogfile.log'; 
    open (my $fl, '<:encoding(UTF-8)', $file) 
         or die 'File not found'; 
    my %ids; 
    
    while (my $row = <$fl>) { 
         if ($row =~ m/\<(\d+).*\>\sclient\sversion\s(\d+.\d+.\d+)\s/i) { 
         my ($id,$vers)=($1,$2); 
         $ids{$id}=$vers; 
        } 
        elsif ($row =~ m/\<(\d+)\:(.+)\(\d+\)\>.*authenticated/i) { 
         if (defined $ids{$1}) { 
          print "$1 : $2 : $ids{$1}\n"; 
          delete $ids{$1}; 
         } 
        } 
    } 
    
    関連する問題