-5

If file size is very big, opening the file in perl will take some time. If I want only first/last 10 lines from the file, parsing the total file in memory and then get those lines should not be a optimal solution. I can use qx{head filename} for this purpose. Is any other way like any CPAN for this?

Abhisek
  • 21
  • 2
  • 7
    "Not opening" is not a sane requirement. Not reading all of it into memory at once is probably what you want and need. – tripleee Apr 11 '16 at 06:58
  • Also, "the best" without specifying criteria invites opinionated discussion. Tell us what you need and why, or settle for "a good enough way". – tripleee Apr 11 '16 at 07:00
  • possible duplicate of http://stackoverflow.com/questions/303053/how-can-i-read-lines-from-the-end-of-file-in-perl -- the `head` case is trivial once you have that. – tripleee Apr 11 '16 at 07:03

4 Answers4

4

You have to open the file, and read it line by line until the limit, like this:

use strict;
use warnings;

my $count = 1;

open my $fh, '<', 'huge_filename' or die $!;
while( <$fh> ) {
    print; # Or push into array for further processing
    last if ++$count == 10;
}
close $fh;
Miguel Prz
  • 13,227
  • 26
  • 36
2

You can't get any data from file without opening it. Also, time to open a file does not depend on file size - it should be instant.

If you need only first 10 lines, you have to open it, read 10 lines and close:

my @lines;

open my $fh, '<', $file_name;
for (1..10) {
    my $line = <$fh>;
    chomp $line; # optional, remove "\n" from end of line
    push @lines, $line;
}
close $fh;
el.pescado
  • 17,764
  • 2
  • 43
  • 82
1

Try this. <$fh> return the next line of the file. So iterate with loop.

open my $fh,'<',"file" or die $!;
print scalar <$fh> for 1 .. 10;

You want to store the output in variable try as follow

my @ar;
open my $handler,'<',"split.py" or die $!;
push @ar, scalar <$handler> for 1 .. 2;
print @ar;
Zaid
  • 35,070
  • 14
  • 81
  • 149
mkHun
  • 5,507
  • 1
  • 25
  • 65
0

Is any other way

It's easy enough to read just the first 10 lines into memory:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

open my $OUTFILE, '>', 'data.txt';

for my $i (1..100_000) {
    say {$OUTFILE} "hello word $i";
}

close $OUTFILE;

open my $INFILE, '<', 'data.txt';

while (my $line = <$INFILE>) {
    print $line;
    last if $. >= 10;
}

close $INFILE;

--output:--
hello word 1
hello word 2
hello word 3
hello word 4
hello word 5
hello word 6
hello word 7
hello word 8
hello word 9
hello word 10

like any CPAN for this?

For reading only the last 10 lines into memory:

use File::ReadBackwards;

open my $INFILE, '<', 'data.txt';
my $backwards_file = File::ReadBackwards->new('data.txt');

my $i = 1;
while (my $line = $backwards_file->readline) {
    print $line;
    last if ++$i > 10;
}

close $INFILE;

--output:--
hello word 100000
hello word 99999
hello word 99998
hello word 99997
hello word 99996
hello word 99995
hello word 99994
hello word 99993
hello word 99992
hello word 99991
7stud
  • 42,113
  • 12
  • 85
  • 111