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)eskshsintaxis también reconocida porzshybashy 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
bashinvenció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
sedyawkson solo uno. Peroteeywcson extremadamente pequeños (mucho más pequeños quesedyawk). - @TheLibbster sí, de acuerdo con algunas pruebas simples que acabo de hacer, ' en realidad es el doble de rápido como los métodos
sedyawk. (Yoddd 100 MB de/dev/urandomen 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?