Estoy tratando de contar el número de líneas de salida que produce un determinado programa. El problema es que el programa tarda mucho en ejecutarse y quiero mostrar el resultado al usuario. ¿Hay alguna manera de contar el número de líneas que se generó el último comando?
Podría hacer program | wc -l
pero eso no» mostraría el resultado al usuario. Por lo que sé, tengo que hacer program; program | wc -l
, pero el programa tarda al menos un minuto en ejecutarse, por lo que no quiero tener que hacerlo más de una vez. para mostrar un recuento de líneas en la parte inferior.
EDIT:
- ¿Hay alguna forma de mostrar la salida a medida que ocurre (línea por línea) y luego devolver un recuento al final?
Comentarios
Respuesta
Puede usar tee
para dividir el flujo de salida enviando una copia a wc
y la otra copia a STDOUT como de costumbre.
program | tee >(wc -l)
La >(cmd)
es sintaxis bash que significa ru n cmd
y reemplace el >(cmd)
bit con la ruta a (una tubería nombrada conectada a) el STDIN de ese programa.
Comentarios
-
>(cmd)
esksh
sintaxis también reconocida porzsh
ybash
y solo usa canalizaciones con nombre en sistemas que no ' t tiene/dev/fd/n
. - @StephaneChazelas Sí, la mayoría de shells lo admiten, pero ' no está en POSIX, por lo que ' no se puede confiar en que esté en todas partes.
- Sí, solo estaba señalando que la sustitución del proceso no era una
bash
invención como la redacción de su respuesta podría hacer creer. - @TheLibbster Depende de cómo defina eficiente. Este método implica generar 2 procesos adicionales, donde
sed
yawk
son solo uno. Perotee
ywc
son extremadamente pequeños (mucho más pequeños quesed
yawk
). - @TheLibbster sí, de acuerdo con algunas pruebas simples que acabo de hacer, ' en realidad es el doble de rápido como los métodos
sed
yawk
. (Yodd
d 100 MB de/dev/urandom
en un archivo y luego ejecuté ese archivo a través de cada método varias veces)
Respuesta
Una opción es usar awk, que puede hacer el conteo e imprimir en stdout.
program | awk "{ print } END { print NR }"
En awk
, NR es el número de línea actual. Puede lograr lo mismo con perl:
program | perl -pe "END {print "$.\n"}"
O sed
:
program | sed -n "p;$="
Comentarios
- ¿Hay alguna forma de mostrar la salida a medida que ocurre (línea por línea) y luego devolver un recuento al final? ?
Responder
mi opción favorita:
program | grep "" -c
Comentarios
- OP puede haber preguntado algo más, pero vine aquí buscando solo obtener un recuento del número de líneas de salida y no ' No me importa mostrar la salida real, y esto hace el trabajo. ¡Gracias!
Responder
Puede clonar stdout en stderr.
program | tee /dev/stderr | wc -l
De esa forma, la salida estándar de program
» se canaliza a tee
para escribirla en stderr, que es impreso en la consola. tee
también escribe los datos enviados a él en su salida estándar, que se envía a wc
.
Respuesta
Esto podría ser tarde. Pero solo abordaría su pregunta de seguimiento sobre cómo capturar el número contado en una variable.
Esto es lo que desea YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l)
.
Aprovechamos tee
generando dos transmisiones aquí y dirija uno a /dev/stderr
, que aparecerá en su pantalla, y el otro a wc -l
, que informará el número de líneas.
Respuesta
tail -f /var/log/squid/access.log | ( c=0; pl() { echo $c; c=0; }; trap pl SIGHUP; while read a; do (( c=c+1 )); done ) & ( trap "kill $! ; exit" SIGINT; trap "" SIGHUP; while true; do kill -HUP $! ; sleep 1; done)
STDOUT_WRITE_COUNT
), o regístrelo en un archivo / API, al final del programa. WDYT?