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

Hi monks,
I am tring to parse my log files here and running into problems where I can't display the name of the element I am looping trough, but I can print the number of times it shows on the file.
Here is the code, let me know please, where the problem is.
foreach (<LOGFILE>){ #my @ddata; #4 if (/^(.*?)*(.*?)*(.*?)*(.*?)*(.*?)*(.*?)*(.*?)*(.*?)$/gi){ #prin +t starting at the date push (@logg,$1); } } my %count; my $total_count; foreach my $element( @logg ) { #4 ++$count{$element}; $total_count++; } #Sort hash by its values foreach my $element (sort {$count{$a} <=> $count{$b}} keys %count){ print "Name: $element<font color=red size=\"2\">Shows:<b>$count +{$element}</b></font> times.<br>"; }

I want to do this to every $1...$8. Just showing how many times each element was present on the file.
Thanks for the help!

Replies are listed 'Best First'.
Re: Parsing Log File Help!
by Enlil (Parson) on Apr 14, 2004 at 19:54 UTC
    For starters, I would doubt that your regex is doing what you think it is doing because in essence it can be reduced to:
    /^(.+)$/
    (/i is unnecessary as . does not care about case, and /g is not necessary as you will only match the start(^) and end($) once per line as you don't have a /m (if you were dealing with multiline strings), also once it has matched once the conditional is true regardless) and the only difference between your regex and mine would be that in the latter the entire line would be put into $1 instead of $8. Which brings us to the case as to why the name of the element won't show up. It is in $8 not $1. But since it matches you push an empty string each time on to @logg. So then latter when you hashify it end up with one element in the hash (being an empty string), with a total count of however many lines were in your file. Regardless not knowing what you file looks like or what represents an element (i.e. what is supposed to go in $1 .. $8.), we can't further help you on how to rectify the situation.

    update:Upon looking at it further the .+ should actually be actually .*, in which case $1 would be an empty string for empty lines, me changing it to a plus would have skipped blank lines which is different behaviour from what the regex the OP posted.

    -enlil

Re: Parsing Log File Help!
by pbeckingham (Parson) on Apr 14, 2004 at 20:03 UTC

    Taking a guess, I think the first part of your program can be replaced by:

    foreach (<LOGFILE>) { push @logg, split; }
    as the regular expression is not good. But that does assume whitespace-delimited log entries. Could you post a sample of the logfile?

    Update: Changed the assignment to a push. Thanks Enlil.

Re: Parsing Log File Help!
by blue_cowdawg (Monsignor) on Apr 14, 2004 at 20:10 UTC

        I am tring to parse my log files

    Got some sample data for us to chew on? Your regex is very suspect. If we had sample data we could help you figure out the right regex to use.

      Yes, the data file looks like :
      Company Name*345467*YW34567c*activitype*04/15/2004*11:34:10*123456789*1
      Thanks
        If I'm reading this correctly, try:
        foreach (<LOGFILE>) { @fields = split '*', $_; # ... blah, blah, blah ... }
        as for the counting... not sure I follow. If you're trying to count the number of times a specific value shows up in a field (i.e., number of times "company abc", "company xyz", etc. show up in the "company name" field) then perhaps something like:
        %company_count; foreach (<LOGFILE>) { ($company_name, ...) = split '*', $_; $company_count{$company_name} ++; } # foreach sort (keys %company_count) { foreach (sort keys %company_count) { print $_, " showed up ", $company_count{$_}, " times\n"; }
        fits the bill...