In article <1194295056.946003.32300@[EMAIL PROTECTED]
>,
Tiago Peczenyj <tiago.peczenyj@[EMAIL PROTECTED]
> wrote:
>On Nov 5, 4:29 pm, loki harfagr <l...@[EMAIL PROTECTED]
> wrote:
>> On Fri, 02 Nov 2007 13:03:59 -0500, Ed Morton wrote:
>> > On 11/2/2007 12:54 PM, Minh wrote:
>> >> Hi,
>>
>> >> How to get awk prints the last 5 lines of the file and one line
before
>> >> last 10 lines.
>>
>> >> Thanks
>> >> Minh
>>
>> > This should be close:
>>
>> > awk 'NR==FNR{nr++;next} (FNR==nr-11) || (FNR>(nr-5))' file file
>>
>> > Ed.
>>
>> I'm not sure, according to what I understood of the
>> OP request, it wouldn't be:
>> # awk 'NR==FNR{nr++;next} (FNR==nr-10) || (FNR>(nr-5))' file file
>>
>> Anyway, just in case an "hybrid" solution is admitted:
>> # tac file | awk 'NR==11||NR<=5' | tac
>>
>> and, if it should deal with a very big file, this would
>> save a lot of cycles ;-)
>> # tac file | awk 'NR==11||NR<=5; NR==11{exit}' | tac
>
>like a tail -X:
>
>$ seq 22 | awk -v X=5 '{A[NR % X]=$0} END{for(i=1;i<=X;i++) print
>A[((NR - X)+i)%X] }'
>18
>19
>20
>21
>22
>
>In this case
>$ seq 20 | awk -v X=11 '{A[NR % X]=$0} END{for(i=1;i<=X;i++){ if (i>1
>&& i<=X-5) continue; print A[((NR - X)+i)%X] }}'
>10
>16
>17
>18
>19
>20
>
>But, your way is much more simple:
>$ seq 20 | tac | awk 'NR==11||NR<=5; NR==11{exit}' | tac
>10
>16
>17
>18
>19
>20
Keep in mind that each of those programs and pipes are the equivalent of
a pass through the file in AWK. So, passing it twice in AWK is better
than something like:
sed|tac|awk|tac
Note also that it is possible to do it in a single pass in AWK, by
writing a "ring" data structure. If the file is large enough, it
becomes worthwhile to go ahead an implement the ring.


|