web-dev-qa-db-fra.com

Compter le nombre de lignes de sortie du programme précédent

J'essaie de compter le nombre de lignes de sortie qu'un certain programme produit. Le problème est que le programme prend beaucoup de temps à exécuter et je veux afficher la sortie à l'utilisateur. Existe-t-il un moyen de compter le nombre de lignes de la dernière commande sortie?

Je pourrais faire program | wc -l mais cela ne montrerait pas la sortie à l'utilisateur. Donc, pour autant que je sache, je dois faire program; program | wc -l - mais le programme prend au moins une minute pour s'exécuter, donc je ne veux pas avoir à le faire plus d'une fois juste pour afficher un nombre de lignes en bas.

MODIFIER:

  • Existe-t-il un moyen d'afficher la sortie telle qu'elle se produit (ligne par ligne) puis de renvoyer un décompte à la fin?
33
Libbux

Vous pouvez utiliser tee pour diviser le flux de sortie en envoyant une copie à wc et l'autre copie à STDOUT comme d'habitude.

program | tee >(wc -l)

>(cmd) est une syntaxe bash qui signifie exécuter cmd et remplacer le bit >(cmd) par le chemin d'accès à (un canal nommé connecté à) ce STDIN de ce programme.

44
Patrick

Une option consiste à utiliser awk, qui peut effectuer le comptage et imprimer sur stdout.

program | awk '{ print } END { print NR }'

Dans awk, NR est le numéro de ligne actuel. Vous pouvez accomplir la même chose avec Perl:

program | Perl -pe 'END {print "$.\n"}'

Ou sed:

program | sed -n 'p;$='
11
jordanm

Vous pouvez cloner stdout sur stderr.

program | tee /dev/stderr | wc -l

De cette façon, la sortie standard de program est dirigée vers tee pour être écrite dans stderr, qui est imprimée sur la console. tee écrit également les données qui lui sont redirigées vers sa sortie standard, qui est redirigée vers wc.

5
user26112

mon option préférée:

program | grep "" -c
3
Montells
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)
0
zlob

Cela pourrait être en retard. Mais je voudrais simplement répondre à votre question de suivi sur la façon d'attraper le nombre compté dans une variable.

C'est ce que vous voulez YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Nous profitons de tee pour générer deux flux ici et en diriger un vers /dev/stderr, qui apparaîtrait sur votre écran, et l'autre sur wc -l, qui indiquerait le nombre de lignes.

0
huangzonghao