On Mon, 28 Oct 2002 13:54:28 -0500, [EMAIL PROTECTED] (Nikola Janceski) wrote:
>without using 'tail' how can I get the trailing 5 lines of a large file >quickly, without loading it all to memory? > >is there anyway without pop and shifting through an array foreach line? (<= >this is the only way I could think of doing it) Here is a method that I've used. The idea is to grab a chunk off the end of the file, then load that into an array and print the last "number" of elements. It rely's on you assuming the line length, in order to compute the chunk size. In the example, I've chosen a 400 character line, which takes almost all files into account. It might waste a little memory, but it's pretty fast on big files. ####################################################### #!/usr/bin/perl -w # example for files with max line lengths < 400, but it's adjustable # usage tailz filename numberoflines use strict; die "Usage: $0 file numlines\n" unless @ARGV == 2; my ($filename, $numlines) = @ARGV; my $chunk = 400 * $numlines; #assume a <= 400 char line(generous) # Open the file in read mode open FILE, "<$filename" or die "Couldn't open $filename: $!"; my $filesize = -s FILE; if($chunk >= $filesize){$chunk = $filesize} seek FILE,-$chunk,2; #get last chunk of bytes my @tail = <FILE>; if($numlines >= $#tail +1){$numlines = $#tail +1} splice @tail, 0, @tail - $numlines; print "@tail\n"; exit; ###################################################### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Another method, which is slow, is to go to the end of the file, and count back the number of newlines. ############################################################# #!/usr/bin/perl -w # linux only, # usage tailz filename numberoflines use strict; my $filename = shift or die "Usage: $0 file numlines\n"; my $numlines = shift; my $byte; # Open the file in read mode open FILE, "<$filename" or die "Couldn't open $filename: $!"; # Rewind from the end of the file until count eol's seek FILE,-1, 2; #get past last eol my $count=0; while (1){ seek FILE,-1,1; read FILE,$byte,1; if(ord($byte) == 10 ){$count++;if($count == $numlines){last}} seek FILE,-1,1; if (tell FILE == 0){last} } $/=undef; my $tail = <FILE>; print "$tail\n"; exit; ################################################################## -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]