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 dieksh-Syntax, die auch vonzshundbashund 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
sedundawknur einer sind. Aberteeundwcsind beide extrem klein (viel kleiner alssedundawk). - @TheLibbster Ja, nach einigen einfachen Tests, die ich gerade durchgeführt habe, ist ' tatsächlich ungefähr doppelt so schnell als die Methoden
sedundawk. (Iddd 100 MB/dev/urandomin 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)