SSS
SSS

Reputation: 1430

How to find out whether next line is blank in perl using $_?

I have a text file.

open FILE,"<data.txt";
while(<FILE>) {
  print $_;
  if($_ =~ m/Track/) {
    # do something ......
    #if next line is blank do something else....
  }
}

But how to find out that? Any idea?

Upvotes: 1

Views: 225

Answers (4)

dlamblin
dlamblin

Reputation: 45341

In general I like the other suggestion(s) to save your state on this line, find the line that matches your future condition and check the past condition.

Yet specifically for this kind of thing you're talking about I like slurping in the file and using an expression that finds the two lines that you are looking for. It's much easier if you just end up wanting to use s///mg instead of the m//;

open FILE,"<data.txt";
my $text = do { local( $/ ) ; <FILE> } ;
close FILE; 
# the slurping I mentioned is now done.
my $tail = "";
while($text =~ m/\G((?:.|\n)*?)^.*Tracks.*$/mg) {
  print $1;
  if($text =~ m/\G.^$/ms) {
    print "the next line is blank";
  } else { 
    print "wait,";
  }
  $text =~ m/(\G.*)/ms;
  $tail = $1;
}
print $tail;

I'm not too happy about the $tail parts above, but I was trying to avoid the use of the $' and $& which was said to slow all matchers. Also I'm not sure this works if the file didn't contain any lines containing "Tracks".

I tested this on:

Hello,
I am going to tell you a story
about a line containing Tracks
that isn't followed by a blank line though
and another line containing Tracks which was

And then only the one word
Tracks
not followed by a blank line

As opposed to
Tracks

and that's the story.

and got:

Hello,
I am going to tell you a story
wait,
that isn't followed by a blank line though
the next line is blank

And then only the one word
wait,
not followed by a blank line

As opposed to
the next line is blank

and that's the story.

Upvotes: 0

ysth
ysth

Reputation: 98398

Some other ideas, depending on what else you are doing:

Read backwards with File::ReadBackwards and keep track of whether the "previous" line was blank or not.

Read in paragraph mode ($/ = "") and match /(^.*Track.*\n)(.)?/m, doing something different based on $2 is defined or not.

Use Tie::File to tie the file to an array and loop over its indexes.

Upvotes: 1

ikegami
ikegami

Reputation: 385887

You haven't read the next line yet, so you can't check if it's blank. Instead, you have to use a buffer to allow you to work with earlier lines once you encounter a blank line.

my $last;
while (<>) {
   s/\s+\z//;
   if ($.>1 && !length) {
      ...do something with $last...
   }

   $last = $_;
}

Upvotes: 4

Greg Hewgill
Greg Hewgill

Reputation: 993213

You can't make any decisions based on the contents of the next line, if you haven't read the next line yet. But you could do something like:

open FILE,"<data.txt";
my $current = <FILE>;
my $next;
while(<FILE>) {
  $next = $_;
  print $current;
  if ($next) {
      # do something ......
  } else {
      #if next line is blank do something else...
  }
  $current = $next;
}

You'll also have to decide exactly what you want to do when you get to the end of the file and there is no next line to read.

Upvotes: 2

Related Questions