PYPL
PYPL

Reputation: 1849

Step back by line in file

I'm iterating through a file and after some condition I have to step back by a line

when file line match the regexp, the second while loop goes in and it iterates over a file until it match while's condition, after than my code have to STEP BACK by 1 line!

while(my $line = <FL>){
 if($line =~ /some regexp/){
   while($line =~ /^\+/){
      $line = <FL>; #Step into next line
   }
   seek(FL, -length($line), 1); #This should get me back the previous line
   #Some tasks with previous line
 }
}

actually seek should work but it doesn't, it return me the same line... What is the problem?

Upvotes: 0

Views: 610

Answers (2)

Miller
Miller

Reputation: 35198

When you read from a filehandle, it has already advanced to the next line. Therefore if you go back the length of the current line, all you're doing is setting up to read the line over again.

Also, relating the length of a line to its length on disk assumes the encoding is :raw instead of :crlf or some other format. This is a big assumption.

What you need are state variables to keep track of your past values. There is no need to literally roll back a file handle.

The following is a stub of what you might be aiming to do:

use strict;
use warnings;

my @buffer;

while (<DATA>) {
    if (my $range = /some regexp/ ... !/^\+/) {
        if ($range =~ /E/) {                   # Last Line of range
            print @buffer;
        }
    }

    # Save a buffer of last 4 lines
    push @buffer, $_;
    shift @buffer if @buffer > 4;
}

__DATA__
stuff
more stuff
some regexp
+ a line
+ another line
+ last line
break out
more stuff
ending stuff

Output:

some regexp
+ a line
+ another line
+ last line

Upvotes: 1

Hamster
Hamster

Reputation: 680

What about something like: (as an alternative)

open(my $fh, '<', "$file") or die $!;#use three argument open
my $previous_line = q{}; #initially previous line would be empty
while(my $current_line = <$fh>){
  chomp;
  print"$current_line\n";
  print"$previous_line\n";
  #assign current line into previous line before it go to next line
  $previous_line = $current_line; 
}
close($fh);

Upvotes: 0

Related Questions