É sempre tão desajeitado, mas você pode adicionar todas as linhas a uma matriz e, no final, quando souber a duração, exibir tudo, exceto as últimas três linhas.
... | awk '{l[NR] = $0} END {for (i=1; i<=NR-3; i++) print l[i]}'
Outra abordagem (mais eficiente aqui ) é o empilhamento manual em três variáveis:
... | awk '{if (a) print a; a=b; b=c; c=$0}'
a só imprime depois que uma linha foi movida de c para b e, em seguida, para a , portanto, isso limita a três linhas. O upsides imediato é que ele não armazena todo o conteúdo na memória e não deve causar problemas de buffer ( fflush() após a impressão se isso acontecer), mas a desvantagem aqui é que não é simples escalar isso. Se você quiser pular as últimas 100 linhas, você precisa de 100 variáveis e 100 variáveis juggles.
Se o awk tivesse operadores push e pop para matrizes, seria mais fácil.
Ou podemos pré-calcular o número de linhas e até onde queremos ir com $(($(wc -l < file) - 3)) . Isso é relativamente inútil para o conteúdo transmitido , mas em um arquivo, funciona muito bem:
awk -v n=$(($(wc -l < file) - 3)) 'NR<n' file
Geralmente, você só usa head :
$ seq 6 | head -n-3
1
2
3
Usando o benchmark de terdon , podemos ver como eles se comparam. Eu pensei em oferecer uma comparação completa:
-
head: 0.018s (me) -
awk+wc: 0.169s (eu) -
awk3 variáveis: 0.178s (me) -
awkdouble-file: 0.322s (terdon) -
awkbuffer circular: 0.355s (Examinador) -
awkfor-loop: 0.693s (eu)
A solução mais rápida é usar um utilitário otimizado para C, como head ou wc , lidar com coisas pesadas, mas em puro awk , a pilha de rotação manual é a melhor opção por enquanto. / p>