numlock00 has asked for the wisdom of the Perl Monks concerning the following question:

I have a nested 'while' loop that won't repeat, no matter how many times the outer loop repeats. The outer loop reads through an array of elements; the inner loop Ithe 'while' loop) is supposed to apply each of these elements while reading an input file.

The outer loop is working fine. It will run through every element of the array. The inner loop, however, only runs once. Even though the outer loop finishes inormally, the inner loop does not repeat. Any help appreciated.

Here it is:
foreach $hour (@hourRange) { $timeBlock = $timeDateBase . $hour; print "$timeBlock\n"; while (<LOG>) { chomp; if ($_ =~ /$timeBlock/) { print "$timeBlock\n"; ($a,$b,$c) = split(/"/, $_); if ($a =~ /^(\S+)\s-\s-\s\[(\S+)\s/) { $IP = $1; $timeString = $2; print "$IP\n"; print "$timeString\n"; } } } }

Replies are listed 'Best First'.
Re: Nested loop won't repeat
by Corion (Patriarch) on Jul 14, 2008 at 11:51 UTC

    I'm guessing here from your naming convention.

    Once you reach the end of your logfile, you need to either seek back to the start for the next $hour or you need to invert your logic (which will likely be faster overall) and for each line in LOG, look through your @hourRange whether it matches or not.

      Thanks much. It worked. I used seek () rather than re-open the file in each loop numlock00
Re: Nested loop won't repeat
by massa (Hermit) on Jul 14, 2008 at 12:47 UTC
    1. putting your code into <code> tags:
      foreach $hour ( @hourRange ) { $timeBlock = $timeDateBase . $hour; print "$timeBlock\n"; while( <LOG> ) { chomp; if( $_ =~ /$timeBlock/ ) { print "$timeBlock\n"; ( $a, $b, $c ) = split( /"/, $_ ); if( $a =~ /^(\S+)\s-\s-\s\[(\S+)\s/ ) { $IP = $1; $timeString = $2; print "$IP\n"; print "$timeString\n"; } } } }
    2. re-seek or re-open your file before going thru it again and again:
      foreach my $hour ( @hourRange ) { my $timeBlock = $timeDateBase . $hour; print "$timeBlock\n"; seek LOG, 0, 0; ## <== seek to the begin of LOG while( <LOG> ) { chomp; if( $_ =~ /\Q$timeBlock\E/ ) { print "$timeBlock\n"; my($a) = split( /"/, $_ ); ## <== only used $a if( $a =~ /^(\S+)\s-\s-\s\[(\S+)\s/ ) { my $IP = $1; my $timeString = $2; print "$IP\n"; print "$timeString\n"; } } } }
      []s, HTH, Massa
Re: Nested loop won't repeat
by apl (Monsignor) on Jul 14, 2008 at 12:10 UTC
    Slightly off-topic, sorry... If you bracket your code with <code> and </code>, you'll make it easier for us to 'see' what your program looks like.

    On-topic... well Corion said it all.

      My apologies. Indeed, I will use markup next time... numlock00
Re: Nested loop won't repeat
by ikegami (Patriarch) on Jul 15, 2008 at 03:28 UTC
    If the log entries are sorted by time and if @hourRange is sorted and contains no duplicates, you could modify your code to process the file once instead of once per element of @hourRange.