Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

How to 'peek' at next line while parsing with <>

by Anonymous Monk
on Jul 11, 2002 at 16:51 UTC ( #181068=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Using the while (<>) construction takes a file from the command line and parses each individual line of the file (up to the \n). How do I 'peek' at the next line in the file without losing my current place? Doing something like:

my $nextLine = <>

would skip the current line, but all I want to do is check the next line for before processing the current line.

I have written all sorts of convoluted test code, trying to fiddle with line numbers, the @ARGV array, the $_ variable, but nothing has worked so far.

Many thanks for your help.

Comment on How to 'peek' at next line while parsing with <>
Select or Download Code
Re: How to 'peek' at next line while parsing with <>
by japhy (Canon) on Jul 11, 2002 at 16:57 UTC
    Well, you can always use redo()...
    while ($line = <>) { # redo comes HERE # do something my $next = <>; if ($next !~ /^#/) { # if the next line DOES NOT start with a "#" # reuse it and restart this iteration of the loop $line = $next; redo; } }
    Or you can use seek() and tell() to make Perl think nothing ever happened:
    while ($line = <>) { # ... my $pos = tell ARGV; my $next = <>; seek ARGV, $pos, 0; # ... }

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: How to 'peek' at next line while parsing with <>
by talexb (Canon) on Jul 11, 2002 at 16:59 UTC
    Depending on the size of the input file, you could
    1. Read the file into an array if the file is not too large; or
    2. Arrange to pretend that the current line from the diamond operator is the 'next' line and the last line is the 'current' line.

    --t. alex

    "Mud, mud, glorious mud. Nothing quite like it for cooling the blood!" --Michael Flanders and Donald Swann

      Number two was also what I had in mind. Something like the following:

      #! /usr/bin/perl use strict ; use warnings ; my $line = <> ; my $queued_line = '' ; chomp $line ; while ( $queued_line = <> ) { chomp $queued_line ; $line =~ m|<(.+?)>| ; print "Found match: [$1] (next line: $queued_line)\n" ; $line = $queued_line ; } $line =~ m|<(.+?)>| ; print "Found match: [$1] (last line)\n" ;

      _______________
      D a m n D i r t y A p e
      Home Node | Email
Re: How to 'peek' at next line while parsing with <>
by BrowserUk (Pope) on Jul 11, 2002 at 17:08 UTC

    This will do what you want - I'm using <DATA> for test purposes. use <> for yours.

    #!perl -w use strict; while (<DATA>) { chomp; print "current line=$_\n"; if (/check next/) { my $pos = tell(); my $testline = <DATA>; chomp $testline; print "'next line' = $testline\n"; #do something... seek DATA, $pos, 0; } print "current line=$_\n"; } __DATA__ line 1 line 2 line 3 check next line 4 OK? line 5

    Anyone know of an abbottoire going cheap?

Re: How to 'peek' at next line while parsing with <>
by Abigail-II (Bishop) on Jul 11, 2002 at 17:14 UTC
    You cannot in general. With non-seekable handles (pipes, STDIN, sockets, fifo, etc) you can't seek back, and usually you can't put something back in the stream either.

    But you can use a buffer. The simplest is a one-scalar buffer. If you want to look, read in the line in a scalar, later, if you want to process the line, process the scalar. You can wrap this up in a module, and if you want to be fancy, you tie it to a filehandle. Or with perl 5.8, you should be able to write an IO layer that does that for you.

    Abigail

Re: How to 'peek' at next line while parsing with <>
by particle (Vicar) on Jul 11, 2002 at 18:38 UTC
    here's a buffered method:

    #!/usr/bin/perl use strict; use warnings; { $_ = <DATA>; my $next_line; while( $next_line = <DATA> ) { print "current line: $_ -- next line: $next_line$/"; } continue { $_ = $next_line; } } __DATA__ 1 2 3 4 5
    yeilds:

    current line: 1 -- next line: 2 current line: 2 -- next line: 3 current line: 3 -- next line: 4 current line: 4 -- next line: 5
    note: the last line is not processed.

    ~Particle *accelerates*

Re: How to 'peek' at next line while parsing with <>
by TexasTess (Beadle) on Jul 11, 2002 at 18:45 UTC
    Why not just read it into a $scalar variable for checking before assigning it where you really want it to go if it meets the conditions....?

    TexasTess
    "Great Spirits Often Encounter Violent Opposition From Mediocre Minds" --Albert Einstein

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2015-07-04 23:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls