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

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

  • Que diriez-vous: demandez au programme de garder une trace de sa propre sortie et de lire simplement cette valeur à partir de la variable (par exemple STDOUT_WRITE_COUNT), ou enregistrez-le dans un fichier / API, à la fin du programme. WDYT?

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 syntaxe ksh également reconnue par zsh et bash 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 et awk nen sont quun. Mais tee et wc sont tous deux extrêmement petits (bien plus petits que sed et awk).
  • @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 et awk. (Jai dd 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) 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *