Anzahl der Ausgabezeilen des vorherigen Programms zählen


32

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

Ich könnte tun, program | wc -laber das würde dem Benutzer die Ausgabe nicht zeigen. Soweit ich weiß, muss ich das tun program; program | wc -l- aber das Programm braucht mindestens eine Minute, damit ich es nicht mehr als einmal ausführen muss, nur um die Zeilenanzahl unten anzuzeigen.

BEARBEITEN:

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

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

Antworten:


43

Sie können teeden Ausgabestream wcaufteilen, indem Sie wie gewohnt eine Kopie an und die andere Kopie an STDOUT senden.

program | tee >(wc -l)

Die >(cmd)is-bash-Syntax bedeutet, cmddass das >(cmd)Bit ausgeführt und durch den Pfad (eine Named Pipe, mit der es verbunden ist) zum STDIN des Programms ersetzt wird.


2
>(cmd)wird kshauch erkannt Syntax zshund bashund wird nur mit Named Pipes auf Systemen, die nicht über /dev/fd/n.
Stéphane Chazelas

@StephaneChazelas Ja, die meisten Shells unterstützen es, aber es ist nicht in POSIX enthalten, daher kann man sich nicht darauf verlassen, dass es überall ist.
Patrick

Ja, ich habe nur darauf hingewiesen, dass Prozessersetzung keine bashErfindung ist, da der Wortlaut in Ihrer Antwort einen glauben lassen könnte.
Stéphane Chazelas

1
@TheLibbster Hängt davon ab, wie Sie effizient definieren. Bei dieser Methode werden 2 zusätzliche Prozesse erzeugt, wobei as sedund as awknur ein Prozess sind. Aber teeund wcsind beide extrem klein (viel kleiner als sedund awk).
Patrick

1
@TheLibbster Ja, nach einigen einfachen Tests, die ich gerade durchgeführt habe, ist es ungefähr doppelt so schnell wie die Methoden sedund awk. (Ich habe dd100 MB /dev/urandomin eine Datei geschrieben und diese Datei dann mehrmals durch jede Methode ausgeführt.)
Patrick,

10

Eine Option ist die Verwendung von awk, die das Zählen und Drucken auf stdout ausführen kann.

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

In awkist NR die aktuelle Zeilennummer. Mit Perl können Sie dasselbe erreichen:

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

Oder sed:

program | sed -n 'p;$='

Gibt es eine Möglichkeit, die Ausgabe während des Vorgangs (zeilenweise) anzuzeigen und am Ende eine Zählung zurückzugeben?
Libbux

6

Sie können stdout auf stderr klonen.

program | tee /dev/stderr | wc -l

Auf diese Weise wird programdie Standardausgabe teean stderr weitergeleitet, das auf der Konsole gedruckt wird. teeSchreibt auch die Daten, die an die Standardausgabe weitergeleitet werden, die an die Standardausgabe weitergeleitet wird wc.


3

Meine Lieblingsoption:

program | grep "" -c

1
OP hat vielleicht noch etwas anderes gefragt, aber ich bin hierher gekommen, um nur die Anzahl der ausgegebenen Zeilen zu zählen, und es war mir egal, ob die tatsächliche Ausgabe angezeigt wird, und das erledigt den Job. Vielen Dank!
Nikhil VJ

0
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

Das könnte zu spät sein. Aber ich möchte nur Ihre Frage beantworten, wie Sie die gezählte Zahl in einer Variablen abfangen können.

Das ist was du willst YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Wir nutzen den Vorteil, teehier zwei Streams zu generieren und leiten einen an /dev/stderr, der auf Ihrem Bildschirm erscheint, und den anderen an wc -l, der die Anzahl der Zeilen angibt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.