sangramjit basu
sangramjit basu

Reputation: 57

Perl: Manipulating while(<>) loop in file reading

My question is regarding the while loop that reads line from files. The situation is that I want to store values from or the entire next line when the while loop while(<FILEHANDLE>) is performing the action on present line ($_). So what is the way to address this problem? Is there a specific function or module that does this thing?

Upvotes: 1

Views: 504

Answers (4)

user1717259
user1717259

Reputation: 2863

If you want to process four lines at a time and each set of lines is separated by @FCC then you need to change perl's input file separator.

In your script put

$/="\@FCC"

This means that when you do (<>), each record you get in $_ is now four lines of your file.

use warnings;
use strict;
local $/="\@FCC";

while (<>) {
    chomp;
    #Each time we iterate, $_ is now all four lines of each record.
}

Edit You'll need to backslash the @

Upvotes: 1

ChatterOne
ChatterOne

Reputation: 3541

If you want to read n lines at a time from a file you can use Tie::File and use an array to reference n elements at a time, like this:

use strict;
use warnings;

use Tie::File;

my $filename = 'path_to_your_file';
tie my @array, 'Tie::File', $filename or die 'Unable to open file';

my $index = 0;
my $size = @array;

while (1) {
    last if ($index > $size); # Be careful! Try to do a better check than this!
    print @array[$index..$index+3];
    print "----\n";
    $index += 4;
}

(This is just an example, try to write better code)

As the documentation says, the file is not loaded into memory all at once, so it will work even for large files.

Upvotes: 0

Doggerel
Doggerel

Reputation: 87

Assuming your file is small-ish (perhaps less than 1gb) you could just stuff it into an array and walk it:

use warnings;
use strict;

my @lines;
while (<>) {
    chomp;
    push @lines, $_;
}

my $num_lines = @lines; #use of array in scalar context give length of array                                             
# don't do last line (there is no next one)                                                                              

$num_lines -= 1;

foreach (my $i = 0; $i < $num_lines; $i++) {
    my $next_line = $i+1;
    print "line $i plus $next_line:",$lines[$i],$lines[$i+1],"\n";
}

Note that the semantics of my solution is a bit different from the answer above. My solution would print out everything except the first line twice; if you wanted everything to be printed once, the above solution might make more sense.

Upvotes: 0

user149341
user149341

Reputation:

You can read from <> anywhere, not just in the head of the loop, e.g.

while (my $line = <>) {
    chomp $line;
    my $another_line = <>;
    chomp $another_line;
    print "$line followed by $another_line\n";
}

Upvotes: 0

Related Questions