Search code examples
stringperlvariableslogfiles

Perl strings into variable calculation


In my code I am searching for some information in bunch of log files that generate every 15 min (the time part is not so important though) and it's giving me certain output as shown below. But that's not what I want.

My end goal is to calculate the output which means I am trying to turn this string of numbers into variables and calculate the total for each restaurant, and then I want to total for all the restaurants.

Honestly I need to track these numbers and calculate the what result I need. I'm so confused with what I have so far so I need help!

I hope I made my concern clear.

Sample log file:

Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 5 for Mcdonalds .....somelog.java:(000)
Total number = 12 for Burger King.....somelog.java:(000)
Total number = 2  for Culvers .....somelog.java:(000)
Total number = 2  for Mcdonalds.....somelog.java:(000)
Total number = 19  for culvers.....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 0 for Mcdonalds .....somelog.java:(000)
Total number = 19  for culvers.....somelog.java:(000)
Total number = 0  for culvers.....somelog.java:(000)

Current output

Total number = 5 for Mcdonalds .....somelog.java:(000)
Total number = 12 for Burger King.....somelog.java:(000)
Total number = 2  for Culvers .....somelog.java:(000)
Total number = 2  for Mcdonalds.....somelog.java:(000)
Total number = 19  for culvers.....somelog.java:(000)

What I need:

Total Number for Mcdonalds = 7
Total Number for Culvers   = 21
Total Number for BK        = 12
Total for all              = 40

Perl Code

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

use File::Find::Rule;
use Date::Parse;

my ($dir,   $type,  $fh,    $line,  $str_1,
    $str_2 );

$dir = '/dir/test/';
$type = '*';
$str_1           = 'Total Number= 0';

$str_2           = '(java:000)';


my @files = File::Find::Rule->file()->name($type)->in($dir);

open $out, '>>', "output_log" or die "Unable to open 'output_log' : $!";
print $out "\Logs \n";
print $out "--------------------------\n";
close $out or die "Unable to finish writing output_log : $!";

for my $file (@files) {

    open $fh,  '<',  $file        or die "can't open $file: $!";
    open $out, '>>', "output_log" or die "Unable to open 'output_log' : $!";

    while ( $line = <$fh> ) {
# Here I am searching for those which are not equal to zero 
#and which has the tail java:(000)

        if ( $line !~ /$str_1/ && $line =~ /$str_2/ ) {
            print $out $line; #So here my output lines are all which are not zero.
        }
    }

    close $out or die "Unable to finish writing output_log : $!";
}

Solution

  • I am assuming that you are getting the output as shown. So I am just focusing on the part to unify them

    #!/usr/bin/perl
    use strict;
    use warnings;
    my $string = "Total number = 5 for Mcdonalds
        Total number = 12 for Burger King
        Total number = 2  for Culvers
        Total number = 2  for Mcdonalds
        Total number = 19  for culvers";
    my @rows = split("\n",$string);
    my %hash = ();
    foreach my $row (@rows) {
        if($row =~ /(\d+)\s+for\s+(.*)$/i) {
            my $comp = lc($2);
            if(exists($hash{$comp})) {
                $hash{$comp} = int($hash{$comp}) + int($1);
            } else {
                $hash{$comp} = int($1);
            }
        }
    }
    foreach (keys(%hash)) {
        print $_ . "...." . $hash{$_} . "\n";
    }