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

Discussion in 'Perl Misc' started by Oxnard, Jun 7, 2005.

  1. Oxnard

    Oxnard Guest

    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?
     
    Oxnard, Jun 7, 2005
    #1
    1. Advertising

  2. Oxnard

    Brian Wakem Guest

    Oxnard wrote:

    > 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?



    --
    Brian Wakem
     
    Brian Wakem, Jun 7, 2005
    #2
    1. Advertising

  3. In article <>,
    Oxnard <> wrote:
    >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'

    --
    Charles DeRykus
     
    Charles DeRykus, Jun 8, 2005
    #3
  4. Oxnard

    Anno Siegel Guest

    Oxnard <> wrote in comp.lang.perl.misc:
    > 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
     
    Anno Siegel, Jun 8, 2005
    #4
  5. Oxnard

    Anno Siegel Guest

    Bernard El-Hagin <> wrote in comp.lang.perl.misc:
    > -berlin.de (Anno Siegel) wrote:
    >
    > > Oxnard <> wrote in comp.lang.perl.misc:
    > >> 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

    >
    >
    > 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
     
    Anno Siegel, Jun 8, 2005
    #5
  6. Oxnard

    Damian James Guest

    On Tue, 7 Jun 2005 14:27:10 -0500, Oxnard 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.

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

    --damian
    --
    @:=grep!(m!$/|#!..$|),split//,<DATA>;@;=0..$#:;while($:=@;){$;=rand
    $:--,@;[$;,$:]=@;[$:,$;]while$:;push@|,shift@;if$;[0]==@|;select$,,
    $,,$,,1/80;print qq x\bxx((@;+@|)*$|++),@:[@|,@;],!@;&&$/} __END__
    Just another Perl Hacker,
     
    Damian James, Jun 8, 2005
    #6
  7. At 2005-06-07 03:27PM, Oxnard <> wrote:
    > 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


    --
    Glenn Jackman
    NCF Sysadmin
     
    Glenn Jackman, Jun 8, 2005
    #7
  8. Damian James wrote:

    > On Tue, 7 Jun 2005 14:27:10 -0500, Oxnard 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
     
    Brian McCauley, Jun 8, 2005
    #8
  9. Oxnard

    Damian James Guest

    On Wed, 08 Jun 2005 18:48:28 +0100, Brian McCauley said:
    > Damian James wrote:
    >> 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
     
    Damian James, Jun 9, 2005
    #9
  10. Damian James wrote:
    > On Tue, 7 Jun 2005 14:27:10 -0500, Oxnard 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
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Jun 9, 2005
    #10
  11. Oxnard

    Bart Lateur Guest

    Oxnard wrote:

    >Assuming the file is a random length text file.


    Try File::ReadBackwards.

    <http://search.cpan.org/search?module=File::ReadBackwards>

    --
    Bart.
     
    Bart Lateur, Jun 9, 2005
    #11
  12. Oxnard

    Chris Guest

    Glenn Jackman wrote:
    > At 2005-06-07 03:27PM, Oxnard <> wrote:
    >
    >> 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
     
    Chris, Jun 15, 2005
    #12
  13. Oxnard

    Damian James Guest

    On Wed, 15 Jun 2005 01:04:00 -0700, Chris said:
    > 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
     
    Damian James, Jun 15, 2005
    #13
  14. * Damian James schrieb:
    > On Wed, 15 Jun 2005 01:04:00 -0700, Chris said:
    >>
    >> 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


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

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

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

    regards,
    fabian
     
    Fabian Pilkowski, Jun 15, 2005
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alain Helfenstein

    Ruby Command Line One Liner

    Alain Helfenstein, Jan 1, 2009, in forum: Ruby
    Replies:
    5
    Views:
    157
    Alain Helfenstein
    Jan 11, 2009
  2. Larry
    Replies:
    1
    Views:
    114
    Martien Verbruggen
    Feb 3, 2005
  3. ahq_2001
    Replies:
    2
    Views:
    121
    Tsu Do Nimh
    May 17, 2005
  4. Mike Pearson

    Single-liner for one-line substitute?

    Mike Pearson, Jun 28, 2006, in forum: Perl Misc
    Replies:
    13
    Views:
    212
    Xicheng Jia
    Jun 30, 2006
  5. boman
    Replies:
    13
    Views:
    273
    boman
    Aug 27, 2009
Loading...

Share This Page