tags:

views:

119

answers:

4

I have a simple log file which is very messy and I need it to be neat. The file contains log headers, but they are all jumbled up together. Therefore I need to sort the log files according to the log headers. There are no static number of lines - that means that there is no fixed number of lines for the each header of the text file. And I am using perl grep to sort out the headers.

The Log files goes something like this:

Car LogFile Header
<text>
<text>
<text>
Car LogFile Header
<text>
Car LogFile Header
<and so forth>

I have done up/searched a simple algorithm but it does not seem to be working. Can someone please guide me? Thanks!

#!/usr/bin/perl

#use 5.010; # must be present to import the new 5.10 functions, notice 
#that it is 5.010 not 5.10


my $srce = "./root/Desktop/logs/Default.log";
my $string1 = "Car LogFile Header";
open(FH, $srce);
my @buf = <FH>;
close(FH);
my @lines = grep (/$string1/, @buffer);

After executing the code, there is no result shown at the terminal. Any ideas?

A: 

Perl grep is not same as Unix grep command in that it does not print anything on the screen.

The general syntax is: grep Expr, LIST

Evaluates Expr for each element of LIST and returns a list consisting of those elements for which the expression evaluated to true.

In your case all the @buffer elements which have the vale of $string1 will be returned.

You can then print the @buffer array to actually see them.

codaddict
I don't get your meaning....
JavaNoob
He means you can't just define an array and expect a screen output from it. To get a screen output you have to `print` the array.
A: 

You just stored everything in an array instead of printing it out. It's also not necessary to keep the whole file in memory. You can read and print the match results line by line, like this:

my $srce = "./root/Desktop/logs/Default.log";
my $string1 = "Car LogFile Header";
open(FH, $srce);
while(my $line = <FH>) { 
  if($line =~ m/$string1/) {
    print $line;
  }
}
close FH;
Still no result shown. It just skips to a blank line in the terminal.
JavaNoob
No, try it with the logfile text you gave above. It will output all the "Car Logfile Header" lines it can find.
A: 

Always use:

use strict;
use warnings;

This would have told you that @buffer is not defined.

#!/usr/bin/perl

use strict;
use warnings;

my $srce = "./root/Desktop/logs/Default.log";
my $string1 = "Car LogFile Header";
open(my $FH, $srce) or die "Failed to open file $srce ($!)";
my @buf = <$FH>;
close($FH);
my @lines = grep (/$string1/, @buf);
print @lines;

Perl is tricky for experts, so experts use the warnings it provides to protect them from making mistakes. Beginners need to use the warnings so they don't make mistakes they don't even know they can make.

(Because you didn't get a chance to chomp the input lines, you still have newlines at the end so the print prints the headings one per line.)

Jonathan Leffler
error appears "readline() on closed filehandle $FH at ./rgex.pl line 9.". Any thoughts on that?
JavaNoob
If you'd checked the return value of the open(), you'd catch that sort of thing.
brian d foy
What version of Perl are you using? It worked OK for me, cut'n'paste from the answer, with 5.13.4, 5.10.1, 5.8.8. It failed with 5.6.2 - couldn't locate strict, which is slightly puzzling...OTOH, it was a PowerPC build of Perl running on my (Intel) Mac running Snow Leopard (10.6.4) and I've not used it in a long time.
Jonathan Leffler
@Brian: oops - I should have added that check...!!!
Jonathan Leffler
Using version 5.8.8
JavaNoob
+2  A: 

I think you want something like:

 my $srce = "./root/Desktop/logs/Default.log";
 my $string1 = "Car LogFile Header";

 open my $fh, $srce or die "Could not open $scre: $!";

 my @lines = sort grep /\Q$string1/, <$fh>;
 print @lines;

Make sure you have the right file path and that the file has lines that match your test pattern.

It seems like you are missing a lot of very basic concepts and maybe cutting and paste code you see elsewhere. If you're just starting out, pick up a Perl tutorial such as Learning Perl. There are other books and references listed in perlfaq2.

brian d foy
I don't get why is the "my" at $fh cause the system's giving this error now "Global symbol "$scre" requires explicit package name" as the $srce should have no problem.
JavaNoob
@JavaNoob: because "$scre" is not spelled the same as "$srce".
Jonathan Leffler
Oops.....Didnt notice that thanks.. But It seems that the codes only print out the header and not the paragraph. I guess must be the question being asked wrong. Anyway its the right answer.
JavaNoob
Provide a short sample file, then show us exactly what you want the output to be. Don't accept this answer if it's not giving you what you need.
brian d foy