Este script permite poner en un archivo las últimas N líneas de una salida. Por ejemplo, ping [...] | alwayslast.bash FILE 10
permitiría que FILE tuviera las últimas 10 líneas de la salida de ping.
This script allows for a file to have the las N lines of an output. For example, ping [...] | alwayslast.bash FILE 10
would make FILE always have the last 10 lines from the output of ping.
#!/bin/bash if [ "$#" -ne 2 ]; then echo "Usage: $0 output_file maxlines" exit 2 fi FILE="$1" MAXLINES="$2" START=0 LINES=1 while IFS= read -r NEWLINE; do BUFFER[START]="$NEWLINE" TEMPFILE=$(mktemp) trap -- 'rm "$TEMPFILE"' EXIT INT TERM for INDEX in $(seq "$((START+1))" "$((LINES-1))") $(seq 0 "$START"); do printf '%s\n' "${BUFFER[$INDEX]}" done > "$TEMPFILE" chmod --reference="$FILE" "$TEMPFILE" mv "$TEMPFILE" "$FILE" trap -- EXIT INT TERM LINES="$((LINES+1))" if [ "$LINES" -gt "$MAXLINES" ]; then LINES="$MAXLINES" fi START="$(((START + 1) % MAXLINES))" done
Gracias a Eduardo Bustamante por sus correcciones.
OUCH… Suena correcto, pero MUY gastalón 🙂
¿Por qué no usas una implementación ampliamente conocida y difundida? Digamos… El comando «last»?
$ genera_salida –larga –demasiado | last -15
Tail (por la sintaxis veo que te referías a tail) sólo arroja las últimas líneas de un stream cerrado. (–follow tampoco es útil en este caso).
Alwayslast.bash va consumiendo la entada estándar de un stream abierto y va exportando a un archivo las que hasta el momento son las últimas N líneas, remplazando el contenido en cada actualización para que queden sólo las últimas N líneas.
Caso de uso: no querer esperar a que corran 30 pings para obtener sus estadísticas sino usar los últimos 30 de un ping que ya está en ejecución como fuente de datos.