How can I grep and sort text files using Perl?

2020-04-06 02:44发布

问题:

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?

回答1:

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 $srce: $!";

 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.



回答2:

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.)



回答3:

I don't think grep is what you want really. As you pointed out in brian's answer, the grep will only give you the headers and not the subsequent lines.

I think you need an array where each element is the header and the subsequent lines up to the next header.

Something like: -

#!/usr/bin/perl

use strict;
use warnings;

my $srce = "./default.log";
my $string1 = "Car LogFile Header";
my @logs;
my $log_entry;
open(my $FH, $srce) or die "Failed to open file $srce ($!)";

my $found = 0;
while(my $buf = <$FH>)
{
    if($buf =~ /$string1/)
    {
        if($found)
        {
            push @logs, $log_entry;
        }

        $found = 1;
        $log_entry = $buf;
    }
    else
    {
        $log_entry = $log_entry . $buf; 
    }
}

if($found)
{
    push @logs, $log_entry;
}

close($FH);

print sort @logs;

i think it's what is being asked for.



回答4:

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.



回答5:

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;


回答6:

Hello I found a way to extract links from html file

!/usr/bin/perl -w

  2 
  3 # Links graber 1.0
  2 
  3 # Links graber 1.0
  4 #Author : peacengell
  5 #28.02.13
  6 
  7 ####
  8 
  9 my $file_links = "links.txt";
 10 my @line;
 11 my $line;
 12 
 13 
 14 open( FILE, $file_links ) or die "Can't find File";
 15 
 16 while (<FILE>) {
 17 chomp;
 18 $line = $_ ;
 19 
 20 @word = split (/\s+/, $line);
 21 @word  = grep(/href/, @word);
 22 foreach  $x (@word) {
 23 
 24 if ( $x =~ m /ul.to/ ){
 25 $x=~ s/href="//g;
 26 $x=~s/"//g;
 27 print  "$x \n";
 28 
 29                         
 30                         }
 31                 
 32                 }
 33         
 34         }

you can use it and modify it please let me know if you modify it.



标签: perl text grep