Michael Alipio wrote:
>
> My Log file looks like this:
> Each session contains at most four lines and then it
> is separated by newline. I need to grab each session
> and put each key/value pair in hash.
>
>
> Start=2006-10-03.09:09:51
> IP=192.168.0.14
> User=alex
> End=2006-10-03.09:14:10
>
> Start=2006-10-03.09:52:12
> IP=192.168.0.15
> End=2006-10-03.09:53:56
>
> Start=2006-10-03.09:55:21
> IP=192.168.0.16
> User=mike
>
> Start=2006-10-03.09:55:38
> IP=192.168.0.17
> End=2006-10-03.09:56:20
>
>
> I'm just following an example given to me.. however at
> some point, I failed to make it work.
>
>
> my $logfile = shift @ARGV;
> open LOGFILE, $logfile or die $!;
> while (<LOGFILE>){
> chomp;
> push @data, $_;
>
> }
> $logdata = "@data";
>
> local $/ = "";
> my $fh = new IO::Scalar \$logdata;
> while (my $record = <$fh>) {
> my %extr;
> for (qw(Start IP User End)){
> $extr{$_} = '';
> $extr{$_} = $1 if $record =~ /$_=(.*)/;
> }
> print "Start:$extr{Start} IP:$extr{IP}
> User:$extr{User} End:$extr{End}";
> }
>
>
> The output is ugly :-(.. I tried trimming my logs to
> only two sessions:
>
> Start=2006-10-03.02:51:48
> IP=192.168.0.14
> User=edison
> End=2006-10-03.04:17:36
>
> Start=2006-10-03.02:51:49
> IP=192.168.0.15
> User=arnel
> End=2006-10-03.04:17:37
>
>
> And I got:
>
> Use of uninitialized value in concatenation (.) or
> string at formatlogs.pl line 51.
> Use of uninitialized value in concatenation (.) or
> string at formatlogs.pl line 51.
> Use of uninitialized value in concatenation (.) or
> string at formatlogs.pl line 51.
> Start:2006-10-03.02:51:48 IP=192.168.0.14 User=edison
> End=2006-10-03.04:17:36  Start=2006-10-03.02:51:49
> IP=192.168.1.15 User=arnel End=2006-10-03.04:17:37 IP:
> User: End:
>
> It's even more uglier.. plus, no matter how I insert
> the newline... the entire output is still shown as a
> single continues line...
>
> Any idea what I am doing?

Hi Michael

You're making life very hard for yourself! First of all there's no neeed to pull
the filename out of @ARGV and do the open and so on yourself: just leave the
@ARGV intact and read using <> and everything else will be done for you.
Secondly it's pointless to read all of the data into a scalar and then read it
again out of there: you may as well process the records as they come in from the
file.

As John points out, the main reason your code is failing is that you've stripped
all the newlines from the data using chomp(), so $logdata continas just a single
line. There will be one space between the fields and two spaces between the
records, so it's still possible to make sense of things from there, but it's a
lot easier if you don't go there in the first place! The program below does all
you want. The output's still a little unpleasant as it uses your original print
format, but you can fix that to do what you need.

HTH,

Rob


use strict;
use warnings;

my %init = map { $_ => '' } qw/Start IP User End/;

local $/ = '';
while (<>) {
  my %extr = %init;
  while (/(\S+)=(\S+)/g) {
    $extr{$1} = $2;
  }
  print "Start:$extr{Start} IP:$extr{IP} User:$extr{User} End:$extr{End}\n";
}

**OUTPUT**

Start:2006-10-03.09:09:51 IP:192.168.0.14 User:alex End:2006-10-03.09:14:10
Start:2006-10-03.09:52:12 IP:192.168.0.15 User: End:2006-10-03.09:53:56
Start:2006-10-03.09:55:21 IP:192.168.0.16 User:mike End:
Start:2006-10-03.09:55:38 IP:192.168.0.17 User: End:2006-10-03.09:56:20


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to