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?
Asked
Active
Viewed 448 times
-5
-
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 Answers
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;
![](../../users/profiles/546205.webp)
Miguel Prz
- 13,227
- 26
- 36
-
Instead of the $count var, you could also use the built in $. , which already had the line number for you. – senorsmile Apr 12 '16 at 04:13
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;
![](../../users/profiles/226648.webp)
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;
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
![](../../users/profiles/926143.webp)
7stud
- 42,113
- 12
- 85
- 111