CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Trying to break from “while loop”

 



testerV
Novice

Nov 22, 2012, 2:42 PM

Post #1 of 14 (2747 views)
Trying to break from “while loop” Can't Post

Hi,
I’m trying to break from “while loop” to start scanning next log.
It should not be complicated but I clearly do not understand how to do that.
Here is the code:

foreach my $file ( @logfile ) {
open my $file_fh,'<', $file or die "Can't open $file $!\n" ;

while ( my $line = <$file_fh> ) {

if ($line !~ /Match1/) {
# next $file ;
}
if ($line =~ /Match1/) {
# do something
}
if ($line =~ /Match2/) {
# do something
}
if ($line =~ /Match3/) {
# do something
}
}
close file_fh ;

Thank you, testerV

Code



      
    


Laurent_R
Enthusiast / Moderator

Nov 22, 2012, 3:18 PM

Post #2 of 14 (2742 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post

Just exit the while loop if you want to go to the next file:


Code
last if $line !~ /Match1/;


You may also use next with a label, but this is not necessary here.


testerV
Novice

Nov 22, 2012, 4:08 PM

Post #3 of 14 (2725 views)
Re: [Laurent_R] Trying to break from “while loop” [In reply to] Can't Post

        while ( $line = <$file_fh> ) {

last if $line !~ /Match1/g ;

if ($line =~ /Match1/) {
print $line ;
}
if ($line =~ /Match2/) {
print $line ;
}
if ($line =~ /Match3/) {
print $line ;
}
}
close $file_fh ;
}

Code
code prints 1st match and exits, it doesn't take next log. 
thanks, testerV


Laurent_R
Enthusiast / Moderator

Nov 22, 2012, 11:06 PM

Post #4 of 14 (2593 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post

In the original code you posted, whenever you are done with a file, you get to the next, thanks to the foreach loop. In this situation, if you exit the while loop with a last statement, you will also get to process next file.

The new code you posted is different, there is no longer a foreach loop going though each file of the list. You can't expect it to pick up next file.


testerV
Novice

Nov 22, 2012, 11:39 PM

Post #5 of 14 (2576 views)
Re: [Laurent_R] Trying to break from “while loop” [In reply to] Can't Post

Hi Laurent!
Thanks for looking in to it man.
Sorry, I posted just a snippet of the same code. I actually want the code to go to the next file if my Match3 is not found in a log.
Here is "almost" the same code:
#!/use/bin/perl -w
use strict;
use warnings ;

my $line ;
my $dir = 'C:/Error_logs' ;
my @logfile = grep( -M $_ < 1, <$dir/*.dat>);
# print @logfile,"\n" ;
foreach my $logfile ( @logfile ) {
open my $logfile_fh,'<', $logfile or die "Can't open $logfile $!\n" ;

while ( $line = <$logfile_fh> ) {
chomp $line ;
last if $line !~ /Match3/g ;

if ($line =~ /Match1/) {
print $line, "\n" ;

}

if ($line =~ /Match2/) {
print $line,"\n" ;

}

last if$line =~ /Match3/g ;
print $line,"\n" ;
}
}
close $logfile_fh ;
}

Code



      
    


Laurent_R
Enthusiast / Moderator

Nov 23, 2012, 12:34 AM

Post #6 of 14 (2550 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post

Hi,

this is a Perl one-liner that prints the first few lines of each *.pl file in my current directory. It lists all the *.pl files, opens each file and prints the content until it finds either the "my" or the use" keyword. When it find one of these words, it simply goes to the next file.


Code
perl -e '@f=glob("*.pl"); for $g (@f) { open $F, "<", $g or die; while (<$F>) {last if /use/ or /my/; print $g, " ", $_;}}'


Try it on your directory.


FishMonger
Veteran / Moderator

Nov 23, 2012, 6:34 AM

Post #7 of 14 (2488 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post

You want to use the 'next' function along with a label, instead of the 'last' function.

http://perldoc.perl.org/functions/next.html


Laurent_R
Enthusiast / Moderator

Nov 23, 2012, 3:08 PM

Post #8 of 14 (2456 views)
Re: [FishMonger] Trying to break from “while loop” [In reply to] Can't Post

The next function with a label is certainly a possible option which will work fine, but in the case in point, I think the last function to exit the while loop and get back into the foreach loop is sufficient and in my humble view algorithmically better constructed. It also enables to cleanly close the current file at the bottom of the foeach loop before opening the next one.


testerV
Novice

Nov 23, 2012, 4:44 PM

Post #9 of 14 (2440 views)
Re: [Laurent_R] Trying to break from “while loop” [In reply to] Can't Post

Hi Lauren, Fish!
Thanks guys for your help!
I made 3 log files to test my script.

File 1 with Match1, Match2 and Match3:

Match1_Er_11111111111111111
Match2_TOOL_111111111111111
Match3__3333333333333333333

File 2 with Match1, Match2 and Match3:

Match1_Er_11111111111111111
Match2_TOOL_111111111111111
Match3__3333333333333333333

File 3 with Match1 and Match2:

Match1_NO
Match2_NO_Tool

When I added the “next function”, it still prints only:

Match3__3333333333333333333
Match3__3333333333333333333
End exits.
I did not try Laurent script yet, it is very complicated.

Here is my code with the Next function:
#!/use/bin/perl -w
use strict;
use warnings ;

my $line ;
my $dir = 'C:/Error_logs' ;
my @logfile = grep( -M $_ < 1, <$dir/*.dat>);
# print @logfile,"\n" ;
foreach my $logfile ( @logfile ) {
open my $logfile_fh,'<', $logfile or die "Can't open $logfile $!\n" ;

LINE: while ( $line = <$logfile_fh> ) {
chomp $line ;
next LINE if $line !~ /Match3/g ;

if ($line =~ /Match1/) {
print $line, "\n" ;

}

if ($line =~ /Match2/) {
print $line,"\n" ;

}

last if$line =~ /Match3/g ;
print $line,"\n" ;
}
close $logfile_fh ;
}


Code


Code

Code

In Reply To


(This post was edited by testerV on Nov 23, 2012, 7:32 PM)


testerV
Novice

Nov 23, 2012, 7:40 PM

Post #10 of 14 (2412 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post

Hi Lauren!
I Just tried your code, it still does not skip a log that does not have ?Match3/ bu thank you for trying to help me.
testerV.

#!/use/bin/perl -w
use strict;
use warnings ;

my ($g,$F) ;
my $dir = 'C:/Error_logs' ;
my @f = grep( -M $_ < 1, <$dir/*.dat>);


for $g (@f)
{ open $F, "<", $g or die; while (<$F>)
{last if /use/ or /my/; print $g, " ", $_;
}
}

Code



      
    


Laurent_R
Enthusiast / Moderator

Nov 24, 2012, 12:54 AM

Post #11 of 14 (2392 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post


In Reply To
Hi Lauren!
I Just tried your code, it still does not skip a log that does not have ?Match3/ bu thank you for trying to help me.


That's not what I understood from your original code. Your original code was trying to break out of a loop if it found a line that matched or did not match a specified pattern. So we assumed that's what you wanted to do, and it now appears you are trying to do something else.

If you want to skip a file that does not have '?Match3/' or whatever other pattern anywhere in the whole file, then this is something entirely different and your algorithm is just plain wrong. You cannot assess whether your log file does not have some particular pattern anywhere until you've read every single line of the file until its very end. So you cannot use next or last to break out of the while loop, because you can't decide what to do before you've read everything.

I hope the difference is clear in your mind.

So you probably need to have a flag set up to false at the beginning of your file. Set it to true if you encounter somewhere the pattern you are looking for. After you've completed reading the file, take the appropriate action depending on whether the flag is still false or has been set to true.

I cannot give you a more detailed approach because you haven't really explained exactly what you are trying to do. Please explain more clearly what you are trying to achieve and provide an example of your input log files.


testerV
Novice

Nov 24, 2012, 4:42 PM

Post #12 of 14 (2351 views)
Re: [Laurent_R] Trying to break from “while loop” [In reply to] Can't Post

Hi Laurent!
You understand is correct, that is exactly what I want to do.
”If you want to skip a file that does not have '/Match3/' or whatever other pattern anywhere in the whole file,…”
And I’m really puzzled how to do this. My plan was like this:
1. Filter all my logs for “new” logs (if ( -M "$dir/$file" < 1 ) )
2. Then filter “new” logs for logs that have /Match3/ and scan these logs for 3 matches /Match1 and Match2 and Match3/ and print all 3 matches out.
I thought I could do this using “foreach” and “while” loops and apparently I cannot do that.

I’m sorry I was not clear on what I need to do man, it is really upsetting for me I thought I could do this by myself and I CANNOT!
Thanks, testerV

Code



      
    


Laurent_R
Enthusiast / Moderator

Nov 25, 2012, 12:45 AM

Post #13 of 14 (2345 views)
Re: [testerV] Trying to break from “while loop” [In reply to] Can't Post


In Reply To
I thought I could do this using “foreach” and “while” loops and apparently I cannot do that.


Yes, you can do this using “foreach” and “while” loops, but you need to read the whole file before you draw any conclusion, what you can't do is to break out of the loop early, you have to scan each file until its very end.


testerV
Novice

Nov 25, 2012, 7:28 PM

Post #14 of 14 (2317 views)
Re: [Laurent_R] Trying to break from “while loop” [In reply to] Can't Post

Hi Lauren!
I can read the whole file but how I can break from the "while" loop now?
Thanks, testerV

my $dir = ''C:/Error_logs' ;
my @logfile = grep( -M $_ < 1, <$dir/*.dat>);
foreach my $file ( @logfile ) {
open my $file_fh,'<', $file or die "CAN'T open $file $!\n" ;

while ( my $line = <$file_fh> ) {
chomp $line ;

if ($line !~ /Match3/...eof ) {
last ;
}
if ($line =~ /Match1/g) {
print $line, "\n" ;
next;
}
if ($line =~ /Match2/) {
print $line, "\n" ;
next;
}
if ($line =~ /Match3/) {
print $line, "\n" ;
next;
}
}
}

Code



      
    

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives