GeekInterview.com
Series: Subject: Topic:
Question: 23 of 65

I was asked how to implement the unix tail command in perl
$ tail.pl t.txt 10 (display last 10 lines)
I kind of managed with the simple ARRAY and they playing around with the $#Array etc.
But they wanted without an array.
Any inputs ?

Asked by: Interview Candidate | Asked on: Jun 14th, 2007
Showing Answers 1 - 15 of 15 Answers
geek2007

Answered On : Jun 21st, 2007

View all answers by geek2007

you can use the following shell command in your perl script .

 `cat filename|tail -10f ;`

  
Login to rate this answer.
Guest

Answered On : Oct 25th, 2007

This may not be accepted as well. But this can be done in numerous ways ! One way is here :

maintain a structure which stores the line number and the size of the file at that time.
eg 1 - 10bytes, 2 - 18 bytes ... you'll have to have a counter to increase the number of lines to find out the number of lines in the file. once you are through the file, you'll know the size of the file at any nth line. use sysseek to move the file pointer back to that position ( last 10 )and then start reading till the end.

  
Login to rate this answer.
imavasu

Answered On : May 13th, 2008

View all answers by imavasu

Please try this capan module

  use File::Tail;
  $file=File::Tail->new("/some/log/file");
  while (defined($line=$file->read)) {
      print "$line";
  }

  use File::Tail;
  $file=File::Tail->new(name=>$name, maxinterval=>300, adjustafter=>7);
  while (defined($line=$file->read)) {
      print "$line";
  }

  
Login to rate this answer.
rahulashu

Answered On : Jun 10th, 2008

View all answers by rahulashu

if we  will passed 2  argument , in that first is  filename  and  second  is no. of  last line then  u can use following  program :

#! /bin/perl

open(MYFILE,$ARGV[0]);

@array = ;
#print @array ;
$numline = @array;
$numprintline = $numline - $ARGV[1] ;
while($numprintline != $numline)
{
        print "$array[$numprintline]" ;
        $numprintline++;
}

  
Login to rate this answer.
nitashaa

Answered On : Jul 16th, 2008

View all answers by nitashaa

#!/usr/bin/perl 
my $count = $ARGV[1];  ---> the number of lines to be printed
while(<>) { ----> reading file passed as arg
my $x = $.;  -----> assigning line number to $x
if ( $count >= $x )
{ print "line number $x: $_n"; }
else { exit; }
}

  
Login to rate this answer.
lbsign

Answered On : Nov 2nd, 2009

View all answers by lbsign

I think the point to not using arrays is the fact that loading large files in to an array is expensive.
$times = 10; # this is the number of lines

open(FILE, "$file") or die ("...");
seek(FILE, 0,2);
my $counter =0;
while ($counter < $times && seek(FILE, -2,1)) {
  read(FILE, $chr, 1);
  if ($chr eq "n") { $counter++ }
}

while () {
  print;
}

close(FILE);

  
Login to rate this answer.
diszgaurav

Answered On : Apr 13th, 2010

View all answers by diszgaurav

How about opening the file twice and get two filehandles, and then navigate:
#!/usr/bin/env perl
# Usage: $0
use warnings;
use strict;

open(FILE1,"$ARGV[0]") or die $!;
open(FILE2,"$ARGV[0]") or die $!;

my $count = $ARGV[1];

while($count--) {
    ;
}

while() {
    ;
}

print ;

close(FILE1);
close(FILE2);

  
Login to rate this answer.
contactparagm

Answered On : Dec 3rd, 2010

View all answers by contactparagm

cat  | perl -e '$i = 0 ; map { print $_ if ($i++ < 10) } reverse (<>)'

  
Login to rate this answer.
lbsign

Answered On : Dec 15th, 2010

View all answers by lbsign

#!/usr/bin/perl

if (@ARGV < 1) {
  die ("Usage: $0 filename [number of lines]n");
}
my $fileName = $ARGV[0];
# defaults to 5 lines if not set
my $noLines = $ARGV[1] || 5;

# Guess how many characters are in a line
my $bytesInLine = 128;
my $bytesInLines = $bytesInLine * $noLines;

open (FILE, "$fileName") or die ("Cannot read $fileNamen");

seek(FILE, 0,2);
my $maxBytes = tell(FILE);

my @fileLines;

my $passCount=0;
my $atBeginFile = 0;

# We want to get the full first line so we get number of lines + 1 
while (@fileLines < $noLines+1) {
  if (!seek(FILE, -1 * $bytesInLines,1)) {
    seek(FILE, 0,0);
    $atBeginFile = 1;
  }
  @fileLines = ;
  $bytesInLines *= 2;
  $passCount++;
  # you passed the beginning of the file
  if ($atBeginFile) {
    # if the requested lines is above the actual file change it
    $noLines = @fileLines;
    last;
  }
}
my $startIndex = @fileLines - $noLines;
@fileLines = splice(@fileLines, $startIndex,$noLines);
print @fileLines;
print "Tailed $noLines lines in $passCount passesn";
close(FILE);

  
Login to rate this answer.

Try this

#!/usr/bin/perl
use strict;
use warnings;

open(FH,"FILENAME") or die "$!";
while ()
{
chomp;
}
print "n$.";
my $x= $. - 10;

close (FH);

open(FH,"FILENAME") or die "$!";
while ()
{
chomp;
if ($.>=$x)
{
  print "$.->$_";
}

}
close (FH);

  
Login to rate this answer.
puneet agrawal

Answered On : Mar 29th, 2012

I think below answer is suitable.

Code
  1. open FILE, "imp.txt" or die $!;
  2. while ($line=<FILE>) {
  3.  push @arr,$line;
  4. }
  5.  
  6.  
  7. ";
  8. $m=$ARGV[0];
  9. for(;$m > 0;$m--){
  10. print @arr[-$m];}

  
Login to rate this answer.
SH

Answered On : Mar 29th, 2012

Open file, read and print until number of required lines is reached. Memory is saved by not slurping the entire file into an array.

Code
  1. $fileName = shift;
  2. $lines = shift;
  3. print "tailing file $fileName for $lines lines...
  4. ";
  5.  
  6. open FH, $fileName or die "Could not open $fileName";
  7.  
  8.     while ($l = <FH>) {
  9.         print $l; --$lines;
  10.         last if $lines == 0;
  11.     }
  12. close FH;

  
Login to rate this answer.
sergant

Answered On : Apr 27th, 2012

View all answers by sergant

Code
  1. #!/usr/bin/perl
  2.  
  3. $fileName = shift;
  4. $lines = shift;
  5. print "tailing file $fileName for $lines lines...
  6. ";
  7.  
  8. open FH, $fileName or die "Could not open $fileName";
  9.  
  10.     while ($l = <FH>) {
  11.         push @ar, $l; --$lines;
  12.         last if $lines == 0;
  13.     }
  14.  
  15.     while ($l = <FH>) {
  16.         push @ar, $l;
  17.         shift @ar;
  18.     }
  19.  
  20. close FH;
  21.  
  22. foreach (@ar) {
  23.     print;
  24. }
  25.  

  
Login to rate this answer.
SumitRoy

Answered On : Sep 16th, 2012

You can also try this : Create two pointers and make them $count apart. Move one of the pointer to EOF and keep simultaneously moving the other pointer so that it is $count before. Now use the second pointer to print the last $count lines.

Code
  1. #!/usr/bin/env perl
  2. use warnings;
  3. use strict;
  4.  
  5. open(FILE1,"$ARGV[0]") or die $!;
  6. open(FILE2,"$ARGV[0]") or die $!;
  7.  
  8. my $count = $ARGV[1];
  9.  
  10. #After this loop FILE1 points to line after $count
  11. while($count--) {
  12. my $line = <FILE1>;
  13.     ;
  14. }
  15.  
  16. #After this loop FILE1 points to EOF and FILE2 points $count before EOF
  17. while(<FILE1>) {
  18. my $line = <FILE2>;
  19.     ;
  20. }
  21.  
  22. #Print the last $count lines before EOF
  23. while(<FILE2>){
  24. }
  25.  
  26. close(FILE1);
  27. close(FILE2);

  
Login to rate this answer.
shiva

Answered On : Nov 22nd, 2012

Just use .. opertor using array just check the length of the array minus with input give by the user take a difference and do it sample code is below.

Code
  1.  
  2. #! /usr/bin/perl
  3.  
  4. my @arry=qw(1 2 3 4 5 6 7 8 9);
  5.  
  6. my $len=$#arry;
  7.  
  8. print "Enter the number";
  9.  
  10. $l=<stdin>;
  11.  
  12. $result=$len-$l;
  13.  
  14. $res=@arry[$len] -@arry[$result];
  15.  
  16.  
  17. foreach my $i (@arry[$result+1].. @arry[$len])
  18. {
  19.   print "
  20. ";
  21.  print $i;
  22.  
  23. }

  
Login to rate this answer.

Give your answer:

If you think the above answer is not correct, Please select a reason and add your answer below.

Related Open Questions

Ads

Connect

twitter fb Linkedin GPlus RSS

Ads

Interview Question

 Ask Interview Question?

 

Latest Questions

Ads

Interview & Career Tips

Get invaluable Interview and Career Tips delivered directly to your inbox. Get your news alert set up today, Once you confirm your Email subscription, you will be able to download Job Inteview Questions Ebook . Please contact me if you there is any issue with the download.