Identique à @muru mais en utilisant l'opérateur modulo au lieu de stocker et de supprimer :
tail -fn+1 some/file | awk -v n=30 '
NR > n {print s[NR % n]}
{s[NR % n] = $0}
END{for (i = NR - n + 1; i <= NR; i++) print s[i % n]}'
Peut-être tamponner avec awk :
tail -n +0 -f some/file | awk '{b[NR] = $0} NR > 30 {print b[NR-30]; delete b[NR-30]} END {for (i = NR - 29; i <= NR; i++) print b[i]}'
Le code awk, développé :
{
b[NR] = $0 # save the current line in a buffer array
}
NR > 30 { # once we have more than 30 lines
print b[NR-30]; # print the line from 30 lines ago
delete b[NR-30]; # and delete it
}
END { # once the pipe closes, print the rest
for (i = NR - 29; i <= NR; i++)
print b[i]
}
Ce n'est pas très efficace, car il relira le fichier deux secondes après l'avoir lu la dernière fois, et vous manquerez des lignes si la sortie arrive trop vite, mais fera autrement le travail :
watch 'tail -n40 /path/to/file | head -n10'