Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Looping through end of file once a match is found

by MBolton (Novice)
on Jun 21, 2005 at 16:04 UTC ( [id://468727]=perlquestion: print w/replies, xml ) Need Help??

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

Hello, I've searched high and low for the answer to my problem, but I've yet to see an example that addresses what I am trying to do. I am hoping that you can help.. Basically, I am reading in a file that in filled with multiple-line log entries. The first line of each log entry has the date (amongst other items) in it in the mm/dd/yyyy format. This Perl script is launched via a web form when a person provides the date that they'd like to search through the logs for (via a dropdown menu on the webpage). If the date that the user requests matches the date in the logfile, it should print everything from that first matching line until the very end of the file. The log is set up in such a manner that the day that the person is requesting will always be the latter portion of the file. With this in mind, here's the code block in question:
LINE: while ($currentfile=<FILE>) { if ($currentfile =~ /^[0-9][0-9][0-9][0-9][0-9][0-9]/){ $match_date = substr($currentfile,52,10); if ($search_date eq $match_date) { print RESULTS "$currentfile"; do { next LINE; print RESULTS "$currentfile"; } until eof(); } #if search_date } # if $currentfile } }
One other note, the reason that I am trying to match on that particular reg ex is because the first line of each log entry (which also includes the date in mm/dd/yyyy format) begins with a six digit sequence number (with leading zeroes). Thanks very much in advance for any guidance!

Replies are listed 'Best First'.
Re: Looping through end of file once a match is found
by Animator (Hermit) on Jun 21, 2005 at 16:37 UTC

    My guess is that you do not know what exactly next does.

    Here is the basic idea: it stops the execution of the current block with the current item, and start all over again with the next item.

    In your code the following two lines will never be executed:

    print RESULTS "$currentfile"; } until eof();

    My guess is that you think it will store the next entry in $currentfile and continue right after the next LINE. This is not the case.

    You could replace the do { } until block with another while (<FILE>) { } or you can go with the suggestion other have already made. (Which are better!)

Re: Looping through end of file once a match is found
by davidrw (Prior) on Jun 21, 2005 at 16:20 UTC
    I believe you can simply replace:
    do { next LINE; print RESULTS "$currentfile"; } until eof();
    With print RESULTS <FILE>; because <FILE> will be treated in array context there and grab everything. After that, execution will fall through naturally and when it tries while ($currentfile=<FILE>) { again, it will be at eof so will break out of that loop.

    Another approach (basically set a flag for when outputting is ok:
    my $matchFound = 0; while ($currentfile=<FILE>) { if( ! $matchFound ){ $matchFound = 1 if $currentfile =~ /^\d{6}/ && $search_date eq sub +str($currentfile,52,10); } next unless $matchFound; print RESULTS $currentfile; }
    And yet another way (take advantage of split), though this involves slurping the log which might be bad if it's large (very untested):
    my $currentfile = do { local $/ = undef; <FILE> }; my @parts = split /(^\d{6}).{46}$search_date)/m, $s, 2; print RESULTS @parts[1,2] if $parts[1];
Re: Looping through end of file once a match is found
by Transient (Hermit) on Jun 21, 2005 at 16:16 UTC
    my $found_date = 0; LINE: while ($currentfile=<FILE>) { if (!$found_date and $currentfile =~ /^\d{6}/){ $match_date = substr($currentfile,52,10); if ($search_date eq $match_date) { $found_date = 1; } } next unless $found_date; print RESULTS "$currentfile"; }
      while ($currentfile = <FILE>) { if ($currentfile =~ /^\d{6}/ and $search_date eq substr($currentfi +le,52,10) { print RESULTS $currentfile; print RESULTS while <FILE>; } }

      Oops. This was supposed to be a reply to the OP, not Transient.

Re: Looping through end of file once a match is found
by mkmcconn (Chaplain) on Jun 21, 2005 at 19:47 UTC

    Would you be looking for something as simple as this ?

    # when $search_date is found beginning in the 52nd column # of a log entry that begins with 6 digits, then # print the matching line and the remainder of the file. my $gate = ''; for(<FILE>){ if ( $gate || ($gate = /^\d{6}.{45}$search_date/)){ print RESULT; } }

    mkmcconn

Re: Looping through end of file once a match is found
by GrandFather (Saint) on Jun 21, 2005 at 21:14 UTC

    There being more than one way to do it:


    Perl is Huffman encoded by design.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://468727]
Approved by dorko
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-03-28 21:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found