É 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) -
awk
3 variáveis: 0.178s (me) -
awk
double-file: 0.322s (terdon) -
awk
buffer circular: 0.355s (Examinador) -
awk
for-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>