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

*** code pasted below, chatter up above **** Hello all, Im relatively new to perl so I hope this question doesnt insult anyone. Im parsing a file and i will need to find one particular line based on a word and then the rest of that file ill need to be able to parse it again. If anyone has a good way of doing this I would love to hear it .. so far I can only create a "marker" that I have found the line and from there create a new array.
1) is there a way to do "@new_array = array that is left".. a pop from the front of the array if you will
or
2)is there a better conditional loop to use ... i thought of while/until but that doesnt seem to work in this case
or
3) someone have a much better way of doing this???? :)
*** code ****
while (<FILE>){ my @arr_hold=$_; foreach my $guide (@arr_hold){ if ( $guide =~ /PAGE: 2/){ $var = 1; } if ($var == "1"){ print FILE2 "$guide"; push (@new_arr,$guide); } } foreach (@new_arr){ print $_; } }
Thanks. R.

Edit Masem 2002-01-23 - Title modified from "newbie question"

Replies are listed 'Best First'.
Re: newbie question
by VSarkiss (Monsignor) on Jan 23, 2002 at 04:21 UTC

    No insult, but I'm having trouble understanding your question. Are you trying to say that you have a file that you're processing line-by-line, and you want to "remember" whether you've seen a particular marker line? (In other words, do something if you've seen the marker line, and another thing if you haven't. I'm kinda guessing that's why you're using two different arrays.) If so, the range operator (..) is perfect for this:

    while (<FILE>) { my $seen_marker = 1 .. /PAGE: 2/; if ($seen_marker) { # one thing } else { # another thing } }
    You can find more information on the range operator here or here.

    HTH

Re: newbie question
by Flame (Deacon) on Jan 23, 2002 at 04:26 UTC
    *Assuming I understand the question any better or worse than anyone else*

    May I ask why you are using a while(<FILE>) loop? It's going to set $_ to one line at a time, so setting an array to $_ isn't going to help you much...

    You could try something like this:
    my @filelines = <FILE>; #Read the entire file into an array my $whichline; #Declare a variable to hold the line number for(my $i = 0; $i = $#filelines; $i++){ #Go through the entire array +untill you find it or run out of lines if($filelines[$i] =~ m/TEXTTOMATCH/o){ #Attempt to match, use compi +le-once $whichline = $i; #If match, remember the line + and leave the loop. last; } }


    Or if you want to find more than one line with that pattern:
    my @filelines = <FILE>; #Read the entire file into an array my @whichline; #Declare a variable to hold the line number for(my $i = 0; $i = $#filelines; $i++){ #Go through the entire array +untill you find it or run out of lines if($filelines[$i] =~ m/TEXTTOMATCH/o){ #Attempt to match, use compi +le-once push(@whichline,$i); #If match, add to the list of current match +es } } #Now you know what lines had TEXTTOMATCH in them
    Once you have the line with that, you can use splice() to remove the line if you wish, or do something else to it...

    **Edit: Inserted comments in code and added multiple match**



    "Weird things happen, get used to it."

    Flame ~ Lead Programmer: GMS

Re: newbie question
by indapa (Monk) on Jan 23, 2002 at 04:22 UTC
    Well from the looks of it, and if I understand your question, you want to print all the lines in the file that matched your regular expression. Try this:
    #!/apps/bin/perl -w use strict; my @lines_that_matched = (); while (<>) { chomp; if (/PAGE: 2/) { push (@lines_that_matched, $_); } } foreach my $line (@lines_that_matched) { print "$line\n"; }
    So if the current line being read has a successful match of the regex, add it to the array of matched lines. After you have read thru the entire file, print each line that matched.
dividing a file in to two parts based on some regexp
by jarich (Curate) on Jan 23, 2002 at 07:15 UTC
    yet another interpretation of your question... You want to go through a file and if you find a word, reparse the whole file or the second part of the file? Perhaps this could help.
    my @file = <FILE>; #all the contents of the file are # now in @file, one line per element my @toppart; my @bottompart; while(@file) { $_ = shift @file; push(@toppart, $_), next unless /PAGE: 2/; # this is reached after the match @bottompart = ($_, @file); last; } # at this point @toppart has all the lines from the file # that were above the first occurance of /Page: 2/ # @bottompart has the first matching line and the rest of # the file. # @file has the same as @bottompart without the matching # line. Obviously if you don't want the matching line # you don't need @bottompart.
    Hope that might help.

    jarich