perl one liner to display the third line from the end of a file

O

Oxnard

perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?
 
B

Brian Wakem

Oxnard said:
perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?


If you are on a proper OS then tail and head would be your best bet I would
think.


system("tail -3 filename | head -1");



What do you want to happen if there are less than 3 lines in the file?
 
C

Charles DeRykus

perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?

yes, but the one-liner society may shun you...

perl -MFile::ReadBackwards -e '$b=File::ReadBackwards->new("your_file");
$l=$b->realine for 1..3;print $l'
 
A

Anno Siegel

Oxnard said:
perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.

perl -ne 'print if $. eq 3' file

If the file is big:

perl -ne '$. eq 3 and print and last' file

Anno
 
A

Anno Siegel

Bernard El-Hagin said:
Subject: Re: perl one liner to display the third line from the end of a
file

Right. Goes to show it's a bad idea to put the question only in the
subject.

perl -ne 'shift @x if @x > 2; push @x, $_; END{ print @x[ 0]}' file

Anno
 
D

Damian James

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?

perl -ne 'BEGIN{$#x=2}push@x,$_;shift@x}{print $x[0]' file

is pleasantly obscure.

Though as another poster suggested, tail -3 | head -1 is the
way to go if obscurity is not on the wish list.

--damian
 
G

Glenn Jackman

At 2005-06-07 03:27PM said:
perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?

Not a high golf score, but you don't have to read every line in the
file. It assumes that the final 3 lines can be contained in the last
1024 bytes of the file though.

perl -e '
open $fid, "<", shift;
$buf = 1024;
seek $fid, -$buf, 2;
$bytes = read $fid, $data, $buf;
@lines = split /\n/, $data, -1; # preserve trailing blank lines
pop @lines; # but ignore the trailing newline that ends the file
print $lines[-3], "\n"
' file
 
B

Brian McCauley

Damian said:
Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.

perl -ne 'BEGIN{$#x=2}push@x,$_;shift@x}{print $x[0]' file

is pleasantly obscure.

Though as another poster suggested, tail -3 | head -1 is the
way to go if obscurity is not on the wish list.

If obscurity is not on the list but Perl is, then Damian's solution is
more clearly written as:

perl -ne 'BEGIN{ $#x=2 } push @x,$_; shift @x; END{ print $x[0] }' file
 
D

Damian James

Damian said:
perl -ne 'BEGIN{$#x=2}push@x,$_;shift@x}{print $x[0]' file

is pleasantly obscure.
...
If obscurity is not on the list but Perl is, then Damian's solution is
more clearly written as:

perl -ne 'BEGIN{ $#x=2 } push @x,$_; shift @x; END{ print $x[0] }' file

*giggles*

Actually, I like Anno's better: principal of least surprise for a file with
less than 3 lines seems to me to be to print the first one, whereas mine
tries to print undef. Oh well.

--damian
 
J

John W. Krahn

Damian said:
Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?


perl -ne 'BEGIN{$#x=2}push@x,$_;shift@x}{print $x[0]' file

is pleasantly obscure.

How about:

perl -ne'BEGIN{$#x=1}($\,@x)=(splice(@x),$_)}{print' file


John
 
C

Chris

Glenn said:
At 2005-06-07 03:27PM said:
perl v5.8.0

Assuming the file is a random length text file.
I know I can do this in a Perl script, however I would like to add the one
liner to an shell script.
Anyone have idea ideas on how to do this?


Not a high golf score, but you don't have to read every line in the
file. It assumes that the final 3 lines can be contained in the last
1024 bytes of the file though.

perl -e '
open $fid, "<", shift;
$buf = 1024;
seek $fid, -$buf, 2;
$bytes = read $fid, $data, $buf;
@lines = split /\n/, $data, -1; # preserve trailing blank lines
pop @lines; # but ignore the trailing newline that ends the file
print $lines[-3], "\n"
' file

Funny that you mention golf scores. A problem very similar to this came
up at work the other day, and a few of the heavyweight perl gurus played
golf with it. I think the question was "how do I return the last 10
lines of a file".

Without slurping the whole file into memory, the two lowest golf scores
were:
perl -ne 'END{print@l}shift@l,if+10<push@l,$_' file
perl -ne 'END{print@l}10<push@l,$_,&&shift@l' file

Including slurping, we got the following gem:

perl -e 'print+(<>)[-10..-1]' file

-chris
 
D

Damian James

Funny that you mention golf scores. A problem very similar to this came
up at work the other day, and a few of the heavyweight perl gurus played
golf with it. I think the question was "how do I return the last 10
lines of a file".

Without slurping the whole file into memory, the two lowest golf scores
were:
perl -ne 'END{print@l}shift@l,if+10<push@l,$_' file
perl -ne 'END{print@l}10<push@l,$_,&&shift@l' file

If it's golf score that matters:

perl -ne '10<push@l,$_,&&shift@l}{print@l' file
Including slurping, we got the following gem:

perl -e 'print+(<>)[-10..-1]' file

Looks optimised to me.

--damian
 
F

Fabian Pilkowski

* Damian James said:
If it's golf score that matters:

perl -ne '10<push@l,$_,&&shift@l}{print@l' file

Without using push() and shift() we could write:

perl -ne '@l=(@l[-9..-1],$_)}{print@l' file

Btw, nice trick with unbalanced "}{" ;-)

regards,
fabian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top