从文件读/写;将匹配的线与线后合并

时间:2015-10-26 20:37:32

标签: perl

我正在读取一个如下所示的日志文件:

[2007/09/06 10:49:30, 0] lib/util_sock.c:write_data(562)
    write_data: write failure in writing to client 158.136.148.93. Error Connection reset by peer
[2007/09/06 10:49:30, 0] lib/util_sock.c:send_smb(769)
    Error writing 4 bytes to client. -1. (Connection reset by peer)
[2007/09/06 10:49:30, 1] smbd/service.c:make_connection_snum(950)
    pubcen04 (158.136.156.79) connect to service sfengel initially as user sfengel (uid=18375, gid=122) (pid 5044)

如果条目包含make_connnection或close_cnum,我将该条目写入另一个名为data.txt的文件。因此,当我的程序匹配一行时,它匹配make_connection所在的行,但我还需要来自其下方的行的信息。我最近尝试这样做是通过使用join函数,但它似乎没有工作。

代码在这里:

#! /usr/bin/perl
use strict;
use warnings;
use IO::File;

my $logfile = 'log.smbd';
my $cnt;

open( my $info, '<', $logfile )
        or die "Could not open file '$logfile' $!";

while( my $line = <$info> ) {
        if( index( $line, 'make_connection' || 'close_cnum') != -1 ) {
                chomp($line);
                $line = join(" ",(<$info> =~ /(\w+)\s+(\w+)/))."\n";
                $line =~ s/\[//g;
                $line =~ s/\]//g;
                my @array = split / /, $line;
                open( my $fh, '>>/etc/data.txt' );
                        print ($fh "\"$array[0]\"\,", "\"$array[1]\"\,",\"$array[5]\"\," );
        }
}

1 个答案:

答案 0 :(得分:-1)

你正在以一种你需要的更难的方式做这件事。首先:

if( index( $line, 'make_connection' || 'close_cnum') != -1 ) {

不会按照您的想法行事 - ||比您想象的更紧密 - 因此您不会测试&#39; close_cnum&#39;一点都不

A || B 

总是返回&#34; A&#34;如果它是真的,&#34; B&#34;如果它不是。并且&#39; make_connection&#39;不是空字符串或零,所以它是&#34; true&#34;。

我建议这样的事情:

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

local $/ = "\n[";

while ( <DATA> ) { 
    next unless m/(make_connection|close_cnum)/; 
    my ( $date, $time, $call, $error_text ) = m/^([\d\/]+) ([\d\:]+). \d+\] (\S+)\n\s*(.*)/m;
    print "Date = $date\n";
    print "time = $time\n";
    print "call = $call\n";
    print "Error = $error_text\n";
    print "Full record:\n";
    print;
    print "\n---\n";
}

__DATA__
[2007/09/06 10:49:30, 0] lib/util_sock.c:write_data(562)
    write_data: write failure in writing to client 158.136.148.93. Error Connection reset by peer
[2007/09/06 10:49:30, 0] lib/util_sock.c:send_smb(769)
    Error writing 4 bytes to client. -1. (Connection reset by peer)
[2007/09/06 10:49:30, 1] smbd/service.c:make_connection_snum(950)
    pubcen04 (158.136.156.79) connect to service sfengel initially as user sfengel (uid=18375, gid=122) (pid 5044)
  • 我们遍历DATA - 这是一个特殊的文件句柄,您可以使用<$info>代替。 (这是用于测试)

  • 但是因为我们已将$/设置为[,所以它会将文件拆分为块,并通过它们进行处理。

  • $_设置为当前块的内容,并对其应用模式匹配以提取所需的文本。 (注意 - 默认情况下,模式匹配适用于$_,这很有用)。

我担心我无法说出你的目标是$array[5],所以我猜对了。但你应该能够分辨出那里发生了什么。