Moe
Moe

Reputation: 1537

Search for string and end when find a keyword

I see that I have made a lot of people confused. Let me clarify.

I have a log file called logdetail.txt. In this file there are a lot of info. in the log file, each user’s info is stored under Final Command Run <command>. Under Each Final Command string, There are info that I need to collect, such as User ID, ID status, expiration date……

logdetail.txt sample

Final Command Run
User ID_1 
Expiration 
Validation Status
More Info 
More info 
Final Command Run
User ID_2
Expiration 
Validation Status
Less info 
Final Command Run
User ID_3
Expiration 
Validation Status
More info

I need my output file logssummary.txt to show something like this

User ID_1, Expiration, Validation
User ID_2,

I change the answer below and I added few things but it's not working.

use strict; 
use warnings;  
use Data::Dumper;  
my @all; 
my %data = (); 

open (Log_summary,">logsummary.txt");
open (INPUTFILE, "logdetail.txt");

while (%data = <INPUTFILE>) {

    next if /^\s*$/;  # skip empty lines     
    if (/^\s*Final\s*$/) {         
    push @all, { %data };         
    %data = ();         
    next;     
    }    
my ($key, $value) = split /\s*=\s*/, $_, 2;    
trim($key); 
trim($value);     
$data{$key} = $value; 
} 
push @all, { %data } if (%data);  # in case there is no Final at the end  print Dumper \@all;  
sub trim {    
     $_[0] =~ s/^\s+//;    
     $_[0] =~ s/\s+$//;
     }

close(INPUTFILE);

print Log_summary "\nNo more input - exiting\n";
print "\nNo more input - exiting\n";
close Log_summary;    

exit; 

Upvotes: 1

Views: 114

Answers (2)

TLP
TLP

Reputation: 67910

As near as I can tell, you have records in between lines denoted with "Begin", and you want to be able to access these. This is a simple hack to parse such a file. I am stripping leading and trailing whitespace, and compensating for whitespace in the formatting.

At each Begin, it will dump whatever is in %data into @all and begin collecting a new set.

If you wish, you can try using the input record separator, $/ to read complete records at once, instead of reading line-by-line. Not sure that would make things easier.

use strict;
use warnings;

use Data::Dumper;

my @all;
my %data = ();
while (<>) {
    next if /^\s*$/;  # skip empty lines
    if (/^\s*Begin\s*$/) {
        push @all, { %data };
        %data = ();
        next;
    }
    my ($key, $value) = split /\s*=\s*/, $_, 2;
    trim($key); trim($value);
    $data{$key} = $value;
}
push @all, { %data } if (%data);  # in case there is no Begin at the end 
print Dumper \@all;

sub trim {
    $_[0] =~ s/^\s+//;
    $_[0] =~ s/\s+$//;
}

Upvotes: 1

Marc B
Marc B

Reputation: 360772

why not just grep '\(Name|ID\)' yourfile.txt > results.txt?

Upvotes: 0

Related Questions