Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hello, ok, after i split a string (delimited by commas) how can i grep the last 3 fields starting from the end? i tried using the cut command in unix but there's no way to cut from right to left.
apple,banana,grape,orange after: banana,grape,orange

Replies are listed 'Best First'.
Re: counting number of fileds
by fruiture (Curate) on Dec 09, 2002 at 20:07 UTC
Re: counting number of fileds
by Enlil (Parson) on Dec 09, 2002 at 20:07 UTC
    If you are already splitting out the string:
    my $string = "apple,banana,grape,orange"; my @fruit_array = split /,/,$string;
    you can access the last three things using array indexes:
    print "$fruit_array[-3], $fruit_array[-2], $fruit_array[-1]\n";
    which prints:

    banana, grape, orange

    -enlil

Re: counting number of fileds
by demerphq (Chancellor) on Dec 10, 2002 at 00:38 UTC
    Heres a one liner:
    perl -ne "@_=split/,/;$a=@_>2?@_-3:0;print join',',@_[$a..$#_]"
    You can pipe into this or pass it a list of filenames that it should convert. It'll print it all to STDOUT.

    I personally think that this is homework. I offer my solution anyway. :-)

    The reason I think its homework is because its one of those simple questions thats easy to get wrong. All of the monks that offered code so far, (fwict) to their collective shame no doubt ;-), have actually not provided working code. And they seem to have some knowledge. No doubt a little more testing, a live sample of the data, whatever and they quickly would have noticed the oversight and fixed it correctly. But the fact remains. :-)

    Anyway, don't think I was any better, I didn't notice the mistake until I did jdporters as a one liner and played with it for a few lines. I'm betting everybody who replied (and maybe a few more, since this'll be at the bottom of the list) are right about now smacking their foreheads and saying "less than three values" :-) (update the grep solution is only backwards...) Cause thats what I did.

    Cheers.

    PS: on *nix I think you spell it

    perl -ne '@_=split/,/;$a=@_>2?@_-3:0;print join",",@_[$a..$#_]'
    but i'm not sure.

    UPDATE If anybody wants to see the results of what has been posted so far read the source of this node.

    --- demerphq
    my friends call me, usually because I'm late....

Re: counting number of fileds
by pfaut (Priest) on Dec 09, 2002 at 20:09 UTC
    Use an array slice.
    $fruits = "apple,banana,grape,orange"; @fruits = split ',',$fruits; # last three elements of the array @last3 = @fruits[$#fruits-2..$#fruits]; print join(',',@last3),"\n";
Re: counting number of fileds
by jdporter (Paladin) on Dec 09, 2002 at 20:13 UTC
Re: counting number of fileds
by pg (Canon) on Dec 09, 2002 at 20:17 UTC
    splice comes to help.
    @a = (1,2,3,4,5,6); @b = splice(@a, $#a - 2, 3); print @b;
Re: counting number of fileds
by insensate (Hermit) on Dec 09, 2002 at 20:49 UTC
    Or with grep ;^)
    $_="1,2,3,4,5,6"; @lastthree=grep{$_ if$i++<3}reverse split/,/;
Re: counting number of fileds
by SuperCruncher (Pilgrim) on Dec 09, 2002 at 20:10 UTC
    First of all, it seems like you need to read up on Perl. Try some of the things suggested at the Learn Perl site.

    split returns a list. You can store this list in an array, e.g. my @bits = split /,/, "foo,bar,baz";. In Perl, you can find out how many elements are in an array by doing scalar @array (or scalar @bits in this case). Subtract one to get the index of the last element. Anyway, you can get at the last three elements by doing: my (@last_three) = ($bits[-1], $bits[-2], $bits[-3]);

    Hope this helps, but make sure you learn Perl properly. You'll thank yourself for it.