Salida del comando 'watch' como una lista

27

Quiero hacer un cálculo simple de la cantidad de líneas por minuto agregadas a un archivo de registro.

También quiero almacenar el recuento por cada segundo.

Lo que necesito es la salida del siguiente comando como una lista que se actualizará cada segundo:

watch -n1 'wc -l my.log'

¿Cómo generar la 'actualización' del comando 'watch' como una lista?

JohnJohnGa
fuente

Respuestas:

24

Puede usar el -tinterruptor watchque hace que no imprima el encabezado. Sin embargo, eso todavía borrará la pantalla, por lo que podría estar mejor con un simple ciclo de shell:

while sleep 1; do
    wc -l my.log
done

Una de las ventajas es que puede agregar fácilmente otros comandos (por ejemplo date) y / o canalizar la salida sedpara formatearla. Por cierto, si intercambias sleep 1con wcen el bucle, terminará automáticamente en caso de errores.

Peterph
fuente
Sin embargo, tenga en cuenta que no lo hará exactamente cada segundo (con zsh o ksh93, puede ajustar el tiempo de sueño para tener en cuenta la deriva incurrida al ejecutar los comandos en el bucle)
Stéphane Chazelas
2
@StephaneChazelas tampoco lo hará wait, solo inténtalo watch -n 1 "sleep 5".
Peter
De hecho (he verificado las implementaciones de procps y busybox). Pensé que era lo único para lo que watchera útil, pero ni siquiera te da eso, por lo que tu solución es tan buena como la basada en el reloj, pero ninguno de los dos responde a la pregunta "velocidad a la que crece un archivo de registro" con gran precisión.
Stéphane Chazelas
Bueno, si las líneas por minuto son el objetivo final, entonces tomar muestras una vez cada 10 segundos es más que suficiente, por lo que la sobrecarga no es tan terrible (a menos que el archivo crezca realmente grande, por supuesto). Y en realidad desde dentro del bucle, uno puede imprimir información de sincronización (incluso antes y después de que el comando termine si es necesario), y luego la precisión puede mejorar (órdenes de magnitud) incluso para archivos más grandes.
Peter
1
@peterph watchtiene una -popción que lo hará bien, si es posible (obviamente, no puede hacer un comando que tome 5 segundos cada 1 segundo, si no se le permiten múltiples simultáneos). Lo sé, lo escribí
:-P
8

Una vieja pregunta, pero acabo de encontrar una respuesta muy fácil:

watch -n1 'wc -l my.log | tee -a statistics.log'

Esto ejecutará wccada segundo, agregará su salida al archivo stats.log y también lo mostrará en la pantalla.
Por lo tanto, terminará con un archivo lleno de números, que representa el número sucesivo de líneas de my.log.

Orabîg
fuente
Tenga en cuenta que este comando watch "($MYCMD | tee -a $MYLOG)"no lo es watch "($MYCMD)" | tee -a $MYLOG. Si te equivocaste como lo hice, la salida será muy confusa. Otra cosa a tener en cuenta aquí es que este comando no agrega la marca de tiempo de la ejecución de cada comando de forma predeterminada, por lo que la respuesta con el bucle podría funcionar mejor para usted.
novato
3

Qué tal si

tail -f file.log | pv -rl > /dev/null
Stéphane Chazelas
fuente
3

Intenta lo siguiente:

watch -n1 'wc -l my.log >> statistics.log'
Andy
fuente
1

Me encontré con esta pregunta cuando estaba tratando de obtener una salida mejor / registrada de du -sh $data_path. Usé el patrón "mientras que el comando, duerme" que se encuentra aquí, pero usé algunos AWK complejos para dar la salida que quería.

while du -sh $data_path; do sleep 1; done | awk '
$1 != size {
    size=$1;
    path=$2;
    time=systime();
    seconds=time-prevtime;
    if(seconds < 1000000000){
        seconds=seconds" seconds"
    }else{
        seconds=""
    }
    print size, path, strftime("%m/%d/%Y@%H:%M:%S", time), seconds; 
    prevtime=time
}'

De hecho, hice esto como una línea, por eso hay puntos y comas. Pero para hacerlo legible, lo saqué. El resultado se ve así:

502G /var/lib/cassandra/dump/ 05/22/2018@04:46:17
503G /var/lib/cassandra/dump/ 05/22/2018@04:46:59 42 seconds
504G /var/lib/cassandra/dump/ 05/22/2018@04:47:57 58 seconds
505G /var/lib/cassandra/dump/ 05/22/2018@04:48:55 58 seconds
506G /var/lib/cassandra/dump/ 05/22/2018@04:49:53 58 seconds
507G /var/lib/cassandra/dump/ 05/22/2018@04:50:50 57 seconds
508G /var/lib/cassandra/dump/ 05/22/2018@04:51:46 56 seconds
509G /var/lib/cassandra/dump/ 05/22/2018@04:52:44 58 seconds
510G /var/lib/cassandra/dump/ 05/22/2018@04:53:41 57 seconds
Bruno Bronosky
fuente
0

Podrías crear un script que lo haga por ti. Llamé al mío keep(sigue haciéndolo) y lo puse en el bincamino.

Este es mi guión:

#!/bin/bash
echo "Repeating command $* every second"
while sleep 1; do
    "$@"
done
Alexandre Santos
fuente
1
Debe usar "$@"para ejecutar el comando (argumentos) en lugar de sin comillas $*. De esta manera, el shell mantendrá los argumentos entre comillas, etc., como el usuario los esperaría. FTFY.
roaima