2

So I'm pretty new to Perl, only been learning it for 1 week. I'm trying to read only a specific range of lines into an array. If I print $_ inside the if statement, it list exactly what i want stored into my array. But storing $_ into my array and then print @array outside the while shows nothing. I'm not sure what I should do. Reason why I'm trying to store it into an array is too get certain information from the columns, therefore needing an array to do so. Thanks for your help. Its probably really simple for you guys

use strict;
use warnings;

my $filename = 'info.text';
open my $info, $filename or die "Could not open $filename: $!";
my $first_line = 2;
my $last_line = 15;

open(FILE, $filename) or die "Could not read from $filename, program halting.";

my $count = 1;
my @lines;

while(<FILE>){
    if($count > $last_line){
        close FILE;
        exit;
    }
    if($count >= $first_line){
        #print $_;
        push @lines, $_;
    }
    $count++;
}
print @lines;

3 Answers 3

2

Much simpler to do it numerically:

my @lines = (<FILE>)[1..14];

(Note - perl arrays start at zero - your 'first' line is 0 in the above)

But you can alternatively keep what you're doing, and test $.:

while ( my $line = <FILE> ) {
    chomp; 
    next unless $. > 2; 
    push ( @lines, $line ); 
    last if $. > 15; 
}

Which should do much the same.

Sign up to request clarification or add additional context in comments.

1 Comment

The only downside of this is that the entire file is read into memory, otherwise it is a lot cleaner.
0

Perl actually has a variable, $., that represents the current line from the most recently used File handle:

From perldoc -v $.:

HANDLE->input_line_number( EXPR )

$INPUT_LINE_NUMBER

$NR

$.

Current line number for the last filehandle accessed.

Each filehandle in Perl counts the number of lines that have been read from it. (Depending on the value of $/ , Perl's idea of what constitutes a line may not match yours.) When a line is read from a filehandle (via readline() or <> ), or when tell() or seek() is called on it, $. becomes an alias to the line counter for that filehandle.

You can use this variable to drastically simplify your code:

use strict;
use warnings;

my $filename = 'info.text';
open(FILE, $filename) 
   or die "Could not read from $filename, program halting.";

my @lines;
while(<FILE>){
    next unless $. >= 2 && $. <= 15;
    push @lines, $_;
}
close FILE;
print @lines;

You can wrap this code, or a modified version in a subroutine that accepts a filehandle, starting line, and ending line to make it more flexible.

Another note that is unrelated to your problem at hand, it is recommended that you always use three argument open.

2 Comments

also if Perl is not a strict requirement here, you can do it with many other linux command line tools. For instance, using head and tail you could say: head -15 filename | tail -n +2
thank you, this has helped alot. what im trying to do, is in each line there are a few columns of numbers separated by spaces. First column is a name and then onward are about 5 columns of numbers. Each line has a different name and different set of numbers. if this makes sense. So trying to add each line total. Quite tricky for a novice. So thought to start out is to store the lines that I'm wanting into an array.
0

There is actually very little wrong with your code. The only reason it doesn't work is that you call exit when the last line of the range has been found. That means the program stops immediately and never executes the print @lines statement

You also open the input file twice for no apparent reason, but that doesn't cause any problems

Here's how I would write it. Note that I've used the autodie pragma so that I don't need to explicitly code error handlers for any of the IO operations

use strict;
use warnings;
use v5.14.1;
use autodie;

use constant FILE       => 'info.text';
use constant FIRST_LINE => 2;
use constant LAST_LINE  => 15;

open my $fh, '<', FILE;

my @lines;

while ( <$fh> ) {
    push @lines, $_ if FIRST_LINE .. LAST_LINE;
    last if $. == LAST_LINE;
}

print @lines;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.