tags:

views:

107

answers:

6

Hi I have a file that has some entries like

--ERROR--- Failed to execute the command with employee Name="shayam" Age="34"

--Successfully executed the command with employee Name="ram" Age="55"

--ERROR--- Failed to execute the command with employee Name="sam" Age="23"

--ERROR--- Failed to execute the command with employee Name="yam" Age="3"

I have to extract only the Name and Age of those for whom the command execution was failed. in this case i need to extract shayam 34 sam 23 yam 3. I need to do this in perl. thanks a lot..

+1  A: 

Your title makes it not clear. Anyway...

while(<>) {
 next if !/^--ERROR/;
 /Name="([^"]+)"\s+Age="([^"]+)"/;
 print $1, "  ", $2, "\n";
}

can do it reading from stdin; of course, you can change the reading loop to anything else and the print with something to populate an hash or whatever according to your needs.

ShinTakezou
Thanks a lot bro.. wont forget you in life.. thanks..
shayam
A: 

Refer to comments :

my @a = <>; # Reading entire file into an array
chomp @a;   # Removing extra spaces
@a = grep {/ERROR/} @a; # Removing lines that do not contain ERROR
# mapping with sed-like regexp to keep only names and ages :
@a = map {s/^.*Name=\"([a-z]+)\" Age=\"([0-9]+)\".*$/$1 $2/; $_} @a; 
print join " ",@a; # print of array content
OMG_peanuts
I would recommend against reading everything into one array and then processing it. Just read it line-by-line.
Matthew Wilson
Don't take it for you, Matthew, but may I ask why ?
OMG_peanuts
If you have a file larger than your RAM, your system would hang. That's why. But more importantly you just don't need to store the entire file in an array - storing the current line in a *single* variable would suffice. Wouldn't it ? :) Or best, just use $_ .
Bart J
Well, may be i'm wrong, but in case of large file, I use Tie::File.I was confronted to a not so large (~30mo) file parsing that took ~180 seconds to perform with a while(<>) loop, against ~4 seconds in slurp mode.As the OP doesn't defined memory usage over execution time as a criteria, i don't think my answer deserve a '-' :(
OMG_peanuts
+5  A: 

As a one-liner:

perl -lne '/^--ERROR---.*Name="(.*?)" Age="(.*?)"/ && print "$1 $2"' file
eugene y
What eerily similar answers! I never remember `-l` though, ++.
daotoad
+2  A: 

As a one liner, try:

perl -ne 'print "$1 $2\n" if /^--ERROR/ && /Name="(.*?)"\s+Age="(.*?)"/;'

This is a lot like using sed, but with Perl syntax.

daotoad
A: 

ah so you like to use perl for something like sed can do. using another tools from perl is easy with "system()" call or backticks.

sir_lichtkind
+2  A: 

The immediate question of "how do I use perl like sed?" is best answered with s2p, the sed to perl converter. Given the command line, "sed $script", simply invoke "s2p $script" to generate a (typically unreadable) perl script that emulates sed for the given set of commands.

William Pursell