Jessaye de compter le nombre de lignes de sortie quun certain programme produit. Le problème est que le programme prend beaucoup de temps à sexécuter et je souhaite afficher la sortie à lutilisateur. Existe-t-il un moyen de compter le nombre de lignes émises par la dernière commande?
Je pourrais faire program | wc -l
mais cela ne montrerait pas la sortie à lutilisateur. Donc, pour autant que je sache, je dois faire program; program | wc -l
– mais le programme prend au moins une minute à courir, donc je ne veux pas avoir à le faire plus dune fois juste pour afficher un nombre de lignes en bas.
EDIT:
- Existe-t-il un moyen dafficher la sortie au fur et à mesure (ligne par ligne) puis de renvoyer un décompte à la fin?
Commentaires
Réponse
Vous pouvez utiliser tee
pour diviser le flux de sortie en envoyant une copie à wc
et lautre copie vers STDOUT comme dhabitude.
program | tee >(wc -l)
Le >(cmd)
est une syntaxe bash qui signifie ru n cmd
et remplacez le bit >(cmd)
par le chemin vers (un tube nommé connecté à) le STDIN de ce programme.
Commentaires
-
>(cmd)
est une syntaxeksh
également reconnue parzsh
etbash
et nutilise que des canaux nommés sur des systèmes qui nutilisent ' t have/dev/fd/n
. - @StephaneChazelas Oui, la plupart des shells le supportent, mais il ' nest pas dans POSIX, donc il ne peut ' pas être invoqué pour être partout.
- Oui, je faisais juste remarquer que la substitution de processus n’était pas un
bash
invention comme le libellé de votre réponse pourrait laisser croire. - @TheLibbster Cela dépend de la façon dont vous définissez lefficacité. Cette méthode implique la création de 2 processus supplémentaires, où
sed
etawk
nen sont quun. Maistee
etwc
sont tous deux extrêmement petits (bien plus petits quesed
etawk
). - @TheLibbster oui, daprès quelques tests simples que je viens de faire, ' est en fait environ deux fois plus rapide comme les méthodes
sed
etawk
. (Jaidd
d 100 Mo de/dev/urandom
dans un fichier, puis jai exécuté ce fichier plusieurs fois dans chaque méthode)
Réponse
Une option consiste à utiliser awk, qui peut faire le comptage et imprimer sur stdout.
program | awk "{ print } END { print NR }"
Dans awk
, NR est le numéro de ligne actuel. Vous pouvez faire la même chose avec perl:
program | perl -pe "END {print "$.\n"}"
Ou sed
:
program | sed -n "p;$="
Commentaires
- Existe-t-il un moyen dafficher la sortie telle quelle se produit (ligne par ligne) et de renvoyer un décompte à la fin ?
Réponse
mon option préférée:
program | grep "" -c
Commentaires
- OP a peut-être demandé autre chose, mais je suis venu ici pour simplement obtenir un nombre de lignes en sortie et je nai pas ' t se soucient dafficher la sortie réelle, et cela fait le travail. Merci!
Réponse
Vous pouvez cloner stdout sur stderr.
program | tee /dev/stderr | wc -l
De cette façon, la sortie stdout de program
» est redirigée vers tee
pour être écrite dans stderr, qui est imprimé sur la console. tee
écrit également les données qui y sont envoyées vers sa sortie standard, qui sont redirigées vers wc
.
Réponse
Il se peut que ce soit tard. Mais je voudrais simplement répondre à votre question de suivi sur la manière dattraper le nombre compté dans une variable.
Voici ce que vous voulez YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l)
.
Nous profitons de tee
pour générer deux flux ici et dirigez lun vers /dev/stderr
, qui apparaîtrait sur votre écran, et lautre vers wc -l
, qui indiquerait le nombre de lignes.
Réponse
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
), ou enregistrez-le dans un fichier / API, à la fin du programme. WDYT?