Anzahl der Ausgabezeilen des vorherigen Programms zählen

Ich versuche, die Anzahl der Ausgabezeilen zu zählen, die ein bestimmtes Programm erzeugt. Das Problem ist das Programm Die Ausführung dauert lange und ich möchte dem Benutzer die Ausgabe anzeigen. Gibt es eine Möglichkeit, die Anzahl der Zeilen zu zählen, die der zuletzt ausgegebene Befehl ausgegeben hat?

Ich könnte program | wc -l ausführen, aber das würde dem Benutzer die Ausgabe nicht anzeigen. Soweit ich weiß, muss ich program; program | wc -l ausführen – aber die Ausführung des Programms dauert mindestens eine Minute, sodass ich es nicht mehr als einmal ausführen muss um eine Zeilenanzahl unten anzuzeigen.

BEARBEITEN:

  • Gibt es eine Möglichkeit, die Ausgabe (zeilenweise) anzuzeigen und am Ende eine Zählung zurückzugeben?

Kommentare

  • Wie wäre es: Lassen Sie das Programm seine eigene Ausgabe verfolgen und lesen Sie einfach diesen Wert aus der Variablen (z STDOUT_WRITE_COUNT) oder protokollieren Sie es in einer Datei / API am Ende des Programms. WDYT?

Antwort

Mit tee können Sie den Ausgabestream aufteilen und eine Kopie an wc und senden die andere Kopie an STDOUT wie gewohnt.

program | tee >(wc -l) 

Die >(cmd) ist Bash-Syntax, was ru bedeutet n cmd und ersetzen Sie das Bit >(cmd) durch den Pfad zur STDIN des Programms (eine mit ihm verbundene Named Pipe).

.

Kommentare

  • >(cmd) ist die ksh -Syntax, die auch von zsh und bash und verwendet nur Named Pipes auf Systemen, die nicht ' t have /dev/fd/n.
  • @StephaneChazelas Ja, die meisten Shells unterstützen dies, aber ' ist nicht in POSIX, damit ' nicht überall verwendet werden kann.
  • Ja, ich habe nur darauf hingewiesen, dass die Prozessersetzung keine Erfindung als Wortlaut in Ihrer Antwort könnte einen glauben lassen.
  • @TheLibbster Hängt davon ab, wie Sie effizient definieren. Bei dieser Methode werden zwei zusätzliche Prozesse erzeugt, wobei sed und awk nur einer sind. Aber tee und wc sind beide extrem klein (viel kleiner als sed und awk).
  • @TheLibbster Ja, nach einigen einfachen Tests, die ich gerade durchgeführt habe, ist ' tatsächlich ungefähr doppelt so schnell als die Methoden sed und awk. (I dd d 100 MB /dev/urandom in eine Datei und führte diese Datei dann mehrmals durch jede Methode)

Antwort

Eine Option ist die Verwendung von awk, mit der gezählt und nach stdout gedruckt werden kann.

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

In awk ist NR die aktuelle Zeilennummer. Sie können dasselbe mit Perl erreichen:

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

Oder sed:

program | sed -n "p;$=" 

Kommentare

  • Gibt es eine Möglichkeit, die Ausgabe (zeilenweise) anzuzeigen und am Ende eine Zählung zurückzugeben ?

Antwort

meine Lieblingsoption:

program | grep "" -c 

Kommentare

  • OP hat vielleicht etwas anderes gefragt, aber ich bin hierher gekommen, um nur die Anzahl der ausgegebenen Zeilen zu ermitteln, und habe nicht ' Es ist nicht wichtig, die tatsächliche Ausgabe anzuzeigen, und dies erledigt den Job. Danke!

Antwort

Sie können stdout auf stderr klonen.

program | tee /dev/stderr | wc -l 

Auf diese Weise wird das stdout von program an tee weitergeleitet, um in stderr geschrieben zu werden tee schreibt auch die an sie weitergeleiteten Daten in die Standardausgabe, die an wc.

Antwort

Dies könnte zu spät sein. Ich möchte jedoch nur Ihre Folgefrage beantworten, wie die gezählte Zahl in einer Variablen abgefangen werden kann.

Dies ist, was Sie wollen YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Wir nutzen den Vorteil, dass tee hier und hier zwei Streams generiert Richten Sie eine an /dev/stderr, die auf Ihrem Bildschirm angezeigt wird, und die andere an wc -l, die die Anzahl der Zeilen angibt.

Antwort

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) 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.