1

I have a log file which looks like below:

 874899 root@commands to execute some files
    Exit Status : 0
    Exit time   : Sun May  5 18:19:39 2013
 874923 root@commands to execute some files
    Exit Status : 2
    Exit time   : Sun May  5 18:19:42 2013

I have a script which looks at a pattern and returns the below line of that matched pattern. The script is as follows:

 open(FH,'log.txt');
 while ($line = <FH>) {
     if ($line =~ /Exit Status/) {
         print "$line";
         print scalar <FH>;
     }
}

I need your input regarding how should I do this, such that it matches the Exit status (as 2 in this case) and save the 874923 line along with the commands (In this case) and the Exit Time as two separate variables.

Please correct me as I am a newbie in perl.

deep
  • 686
  • 4
  • 17
  • 33
  • What do you mean by `Exit Time` as two separate vars? You want the text of it in one var and the date/time in another? – hwnd Jul 10 '13 at 00:57
  • @JasonGray Thank you for your quick reply..Exit Time is just a variable in this case. But are variables as per the log files – deep Jul 10 '13 at 01:04
  • It is unclear from your question what your log file contains. I presume `# Consists of three lines output` isn't in the file, but is `{...}` in there? And are there three lines of data *including* the `Exit Status` and `Exit times`, or are there five lines in total per record? Couldn't you just post some live data? It would be much simpler to understand. – Borodin Jul 10 '13 at 01:10
  • It is almost never right to put a scalar variable inside quotes. `print $line` is correct. – Borodin Jul 10 '13 at 01:13
  • @Borodin Thank you for your reply...I have edited my above question..I require 2 variables which can hold the above lines 874923 and Exit Status if the Exit Status condition equals 2..I hope this helps..Thank you – deep Jul 10 '13 at 01:21
  • @deep It's unclear how you want the result. My guess is you want to store data for any exit status, for ex: 2, and that data would be 874923 line with commands and Exit time for that exit status. If I am not wrong, you are confusing us by saying you need 2 variables. Infact I feel you need 2 lines (commands and exit time) corresponding to every exit status. Is that correct? –  Jul 10 '13 at 08:07

3 Answers3

1

Your code could be like this:

 use Data::Dumper;
 open(FH,'inlog.txt');

 my @stat;

 my ($exitstatus, $exitstatusval, $exittime, $exittimeval, $exitcommands);
 while ($line = <FH>) {
        if ($line =~ m/\d+\s+.*@.*/) {
            $exitcommands = $line;
        }
        if ($line =~ /Exit Status/) {
            ($exitstatus, $exitstatusval) = split(':',$line);
            next;
        }
        if ($line =~ /Exit time/ and $exitstatusval == 2) {
            ($exittime, $exittimeval) = split(': ',$line);
             push (@stat, {
                commands => $exitcommands,
                time => $exittimeval
                });
        }
}

print(Dumper(\@stat));

Output: So this will print 'arrayref of hashrefs' for entries having exit status 2

  $VAR1 = [
          {
            'time' => 'Sun May  5 18:19:42 2013 ',
            'commands' => '874923 root@commands to execute some files '
          },
          {
            'time' => 'Sun May  4 18:19:42 2013',
            'commands' => '874613 root@commands to execute some files '
          }
        ];
  • Thank you for your reply...Your script distinguishes Exit status 0, 1 and 2 for only limited amount of entries..What should I do if there is a file with lot of such entries and I need the information for just Exit Status : 2. Thank you. – deep Jul 11 '13 at 00:27
  • Thank you for your reply.But your code is not getting iterated for the whole file..I am only getting a single value for Exit Status : 2, while it has many variables attached to it..Can you help me to know where I am thinking wrong? Thank you. – deep Jul 11 '13 at 18:30
  • @deep Edited please recheck now –  Jul 11 '13 at 18:56
  • Works like a champ..Thank you @Drt. Also, what changes are required to make it work with a hash..Is there a difference due to non unique key value pair? – deep Jul 11 '13 at 23:26
  • @deep With hash you can have single key as `2` and It will point to arrayref of hash ref. I directly used the arrayref of hashref. You can put the reference of @stat `\@stat` as value for the key `2` so it will work in that case too. –  Jul 12 '13 at 06:26
0

This is how I would do it...

use Data::Dumper;

open(FH,'<','log.txt');
my $current_log;
my @logs;
while (my $line = <FH>) {
  if($line =~ /^\s*(\d+)\sroot\@(.*)/) {
    if($current_log) {
      push @logs,$current_log;
    }
    $current_log = {};
    $current_log->{pid} = $1;
    $current_log->{command} = $2;
  }
  if ($line =~ /Exit Status\s*:\s*(\d+)/) {
    $current_log->{exit_status} = $1;
  }
  if($line =~ /Exit time\s*:\s*(.+)$/) {
    $current_log->{exit_time} = $1;
  }
}
if($current_log) {
  push @logs,$current_log;
}

print Dumper \@logs;

That should print out the following:

$VAR1 = [
      {
        'exit_time' => 'Sun May  5 18:19:39 2013',
        'pid' => '874899',
        'exit_status' => '0',
        'command' => 'commands to execute some files'
      },
      {
        'exit_time' => 'Sun May  5 18:19:42 2013',
        'pid' => '874923',
        'exit_status' => '2',
        'command' => 'commands to execute some files'
      }
    ];
Gordolio
  • 1,925
  • 15
  • 22
0

With the help of hash, this is what I used:

use Data::Dumper;
open(FH,'inlog.txt');

my %stat;

my ($exitstatus, $exitstatusval, $exittime, $exittimeval, $exitcommands);
while ($line = <FH>) {
    if ($line =~ m/^(\d+)\s+.*@(.*)/) {
        $exitcommands = $2;
        $qbsid= $1;
    }
    if ($line =~ /Exit Status/) {
        ($exitstatus, $exitstatusval) = split(':',$line);
        next;
    }
    if ($line =~ /Exit time/ and $exitstatusval == 2) {
        ($exittime, $exittimeval) = split(': ',$line);
         $stat{$qbsid} = {
            commands => $exitcommands,
            time     => $exittimeval
            };
    }

}

  print(Dumper(\%stat));
deep
  • 686
  • 4
  • 17
  • 33