in reply to last $n lines that match a criteria


Here is a one-liner, change 5 and the match criteria to suit.
perl -ne '$a[($i+=1)%=5] = $_ if /foo/; END{print @a[$i+1..@a,0..$ +i]}' file

This reads all the way through the file so it will be less efficient than methods that read backwards through the file.

--
John.

Replies are listed 'Best First'.
Re: Re: last $n lines that match a criteria
by ysth (Canon) on Nov 17, 2003 at 11:19 UTC
    I think you mean ..$#a, not ..@a. This works, too: perl -wpe'$a[($i+=1)%=5]=$_ if /foo/} for(@a[$i+1..$#a,0..$i]){' file

      No, I meant @_ because it came from some golf code and that was one character shorter. :-)

      Here is the progression of code that I took it from (note this is for tail and not the last $n matching lines but the change is minor).

      # tail perl -ne '$i=$.%5; $a[$i]=$_; END{print @a[$i+1..$#a,0..$i]}' file perl -ne 'END{print@a[$i+1..$#a,0..$i]}$a[$i=$.%5]=$_' file perl -ne 'END{print@a[$i+1..@a,0..$i]}$a[$i=$.%5]=$_' file perl -pe '$a[$i=$.%5]=$_}{print@a[$i+1..@a,0..$i]' file perl -pe '$_[$==$.%5]=$_}{print@_[$=+1..@_,0..$=]' file

      Also, I left out -w on purpose for cases where there were less matches than $n. Try this:

      echo foo | perl -wpe 'your code here' file

      That is also why I was able to get away with @a.

      --
      John.

        Whoops, only tried mine with >=5 inputs. You are entirely correct.