pingme8705 has asked for the wisdom of the Perl Monks concerning the following question:

hi frenz ! i find some problem in matching the date and time from the text file.
logging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved disks faults avm fre cs us sy id 504956 19880 32 3 24 72 device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 96% /var 88% / 100% Interleaved disks faults avm fre cs us sy id 5049 198 32 3 24 72 device2 Tue Sep 5 10:26:44 GMT 2005
i have tried the formats like  (\d\d)[-:](\d\d)[-:](\d\d)\s but unable to get the time. Any suggestions ?

Replies are listed 'Best First'.
Re: matching the date and time
by castaway (Parson) on Sep 11, 2005 at 10:31 UTC
    That regex looks fine, so you'll have to show the rest of the code for anyone to try and spot your mistake.

    C.

      hi !
      use warnings; use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("data.xls"); my $worksheet = $workbook->add_worksheet(); $worksheet->write ("A1", 'Device'); $worksheet->write ("B1", '/var'); $worksheet->write ("C1", '/'); $worksheet->write ("D1", 'interleaved'); $worksheet->write ("E1", 'avm'); $worksheet->write ("F1", 'fre'); $worksheet->write ("G1", 'cs'); $worksheet->write ("H1", 'us'); $worksheet->write ("I1", 'sy'); $worksheet->write ("J1", 'id'); #$worksheet->write ("K1", 'Date'); my $row = 2; my $line = ''; my $device; open inFile, '<', 'logs.txt' or die "Couldn't open data.txt: $!"; while (! eof inFile) { $line .= ' ' . <inFile>; chomp $line; next if ! ($line =~ /logging\sto\s(.*?)\s+/i) and ! eof inFile; my $nextDevice = $1; if ($line =~ /(\d+)%\s+\/var\s+(\d+).*?(\d+)%\s+Interleaved\s+.*?avm\s+.* +?fre\s+.*?cs\s+.*?us\s+.*?sy\s+.*?id\s+.*?(\d+)\s+(\d+)\s+(\d+)\s+(\d ++)\s+(\d+)\s+(\w+)/i) { $worksheet->write("A$row", "$device"); $worksheet->write("B$row", "$1"); $worksheet->write("C$row", "$2"); $worksheet->write("D$row", "$3"); $worksheet->write("E$row", "$4"); $worksheet->write("F$row", "$5"); $worksheet->write("G$row", "$6"); $worksheet->write("H$row", "$7"); $worksheet->write("I$row", "$8"); $worksheet->write("j$row", "$9"); #$worksheet->write("j$row", "$10"); ++$row; print "$device $1, $2, $3, $4, $5, $6, $7, $8, $9\n"; } $device = $nextDevice; $line = ''; } close inFile; $workbook->close ();
      this is my code ! this print everything fine except the date and time.
        ($line =~ /(\d+)%\s+\/var\s+(\d+).*?(\d+)%\s+Interleaved\s+.*?avm\s+.* +?fre\s+.*?cs\s+.*?us\s+.*?sy\s+.*?id\s+.*?(\d+)\s+(\d+)\s+(\d+)\s+(\d ++)\s+(\d+)\s+(\w+)/i)
        Your cdoe works fine, except that last (\w+) is $9, which is "72" (the 'id' value) .. you're not capturing the date string at all.. if you just change it to:
        $line =~ /(\d+)%\s+\/var\s+(\d+).*?(\d+)%\s+Interleaved\s+.*?avm\s+.*? +fre\s+.*?cs\s+.*?us\s+.*?sy\s+.*?id\s+.*?(\d+)\s+(\d+)\s+(\d+)\s+(\d+ +)\s+(\d+)\s+(\d+)\s+.*?(\d\d):(\d\d):(\d\d)/i print "$device $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12\n";
        you get the hour/min/sec at the end ...

        You might, however, consider a different approach to making the parsing easier:
        use strict; use warnings; my @devices; while( my $line = <DATA> ){ next unless $line =~ /^\s*logging to (\w+) is ([0-9.]+) . . ./; my %device = ( name => $1, ip => $2, partitions => [], ); do { $line = <DATA>; } until $line =~ /\S/; while( $line =~ /^(\d+)%\s+(\S+)/ ){ push @{$device{partitions}}, { name => $2, pct_used => $1 }; $line = <DATA>; } warn "Expected 'disks faults' line" unless $line =~ /disks faults/; $line = <DATA>; chomp($line); warn "Expected 'avm fre cs us sy id' line" unless $line =~ /avm fre +cs us sy id/; my @cols = split ' ', $line; warn "wrong number of columns" unless scalar(@cols)==6; $line = <DATA>; chomp($line); warn "Expected numbers on '$line'" unless $line =~ /(\d+ ){5}\d+/ && + $line !~ /[^0-9 ]/; my @vals = split ' ', $line; warn "wrong number of values" unless scalar(@vals)==6; @{$device{attributes}}{ @cols } = @vals; $line = <DATA>; chomp $line; warn "Expected device name on '$line'" unless $line eq $device{name} +; $line = <DATA>; chomp $line; if( $line =~ /(\d\d):(\d\d):(\d\d)/ ){ @{$device{date}}{ qw/hour minute second/ } = ( $1, $2, $3 ); }else{ warn "Couldn't parse date line: '$line'"; } push @devices, \%device; } use Data::Dumper; print Dumper \@devices; exit; __DATA__ logging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved disks faults avm fre cs us sy id 504956 19880 32 3 24 72 device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 96% /var 88% / 100% Interleaved disks faults avm fre cs us sy id 5049 198 32 3 24 72 device2 Tue Sep 5 10:26:44 GMT 2005
        (there's many ways to do this -- e.g. another way might be to do something clever with $/)
Re: matching the date and time
by monarch (Priest) on Sep 11, 2005 at 13:43 UTC

    Are you trying to match

    Tue Sep 5 10:26:44 GMT 2005
    ?

    If this is so, then a more appropriate regexp might be:

    /( # start selection \w{3} # Tue \s # one space \w{3} # Sep \s+ # one or more spaces \d+ # 5 (day, one or more digits) \s # one space \d+:\d+:\d+ # 10:26:44 \s+ # one or more spaces (?:\w+\s+)? # optional timezone GMT \d+ # year ) # end of selection /x # x - allows whitespace in regexp

    Or as a one liner:

    /(\w{3}\s\w{3}\s+\d+\s\d+:\d+:\d+\s+(?:\w+\s+)?\d+)/

      hi ! Thank you i am going to try that let you know !
        hi Thank you its working fine. it was a great job.