Ausgabe des Befehls 'watch' als Liste

27

Ich möchte einfach die Anzahl der Zeilen pro Minute berechnen, die zu einer Protokolldatei hinzugefügt wurden.

Ich möchte auch die Zählung für jede Sekunde speichern.

Was ich brauche, ist die Ausgabe des folgenden Befehls als Liste, die jede Sekunde aktualisiert wird:

watch -n1 'wc -l my.log'

Wie kann man das 'Update' des 'Watch'-Befehls als Liste ausgeben?

JohnJohnGa
quelle

Antworten:

24

Sie können den -tSchalter verwenden, auf den watchder Header nicht gedruckt wird. Dadurch wird der Bildschirm jedoch immer noch gelöscht, sodass Sie mit einer einfachen Shell-Schleife möglicherweise besser dran sind:

while sleep 1; do
    wc -l my.log
done

Einer der Vorteile ist, dass Sie einfach andere Befehle hinzufügen können (zB date) und / oder die Ausgabe sedweiterleiten können, um sie neu zu formatieren. Übrigens, wenn Sie in der Schleife sleep 1mit tauschen wc, wird es automatisch bei Fehlern beendet.

peterph
quelle
Beachten Sie jedoch, dass es nicht jede Sekunde genau funktioniert (mit zsh oder ksh93 können Sie die Ruhezeit anpassen, um die Abweichung zu berücksichtigen, die durch das Ausführen der Befehle in der Schleife entsteht)
Stéphane Chazelas,
2
@StephaneChazelas wird es auch nicht mit wait- versuchen Sie es einfach watch -n 1 "sleep 5".
Peterph
In der Tat (ich habe sowohl procps- als auch busybox-Implementierungen überprüft). Ich dachte, das wäre das Einzige, wofür watches nützlich ist, aber es gibt Ihnen nicht einmal das, weshalb Ihre Lösung so gut ist wie eine auf der Uhr basierende, aber auch nicht die Frage, wie schnell eine Protokolldatei wächst , mit großer Genauigkeit beantwortet.
Stéphane Chazelas
Nun, wenn Linien pro Minute das ultimative Ziel sind, ist es imho mehr als genug, sie alle 10 Sekunden abzutasten - der Overhead ist also nicht so schlimm (es sei denn, die Datei wächst wirklich groß, natürlich). Tatsächlich kann man aus der Schleife heraus Timing-Informationen drucken (sogar vor und nach Beendigung des Befehls, falls erforderlich), und dann kann die Genauigkeit auch für größere Dateien verbessert werden (Größenordnungen).
Peterph
1
@peterph watchhat eine -pOption, die dies nach Möglichkeit korrekt ausführt (natürlich können Sie keinen Befehl ausführen, der alle 1 Sekunde 5 Sekunden dauert, wenn Sie nicht mehrere gleichzeitig ausführen dürfen). Ich weiß, ich habe es geschrieben :-P
derobert
8

Eine alte Frage, aber ich habe gerade eine sehr einfache Antwort gefunden:

watch -n1 'wc -l my.log | tee -a statistics.log'

Dadurch wird wcjede Sekunde ausgeführt, die Ausgabe der Datei statistics.log hinzugefügt und auch auf dem Bildschirm angezeigt.
So erhalten Sie eine mit Zahlen gefüllte Datei, die die aufeinanderfolgende Anzahl von Zeilen darstellt my.log.

Orabîg
quelle
Bitte beachten Sie, dass dieser Befehl watch "($MYCMD | tee -a $MYLOG)"nicht watch "($MYCMD)" | tee -a $MYLOG. Wenn Sie das falsch verstanden haben, wie ich, wird die Ausgabe sehr, sehr verwirrend sein. Eine andere Sache, die Sie hier beachten sollten, ist, dass dieser Befehl nicht standardmäßig den Zeitstempel der Ausführung jedes Befehls hinzufügt, sodass die Antwort mit der Schleife möglicherweise noch besser für Sie funktioniert.
ffledgling
3

Wie wäre es mit

tail -f file.log | pv -rl > /dev/null
Stéphane Chazelas
quelle
3

Versuche Folgendes:

watch -n1 'wc -l my.log >> statistics.log'
Andy
quelle
1

Ich bin auf diese Frage gestoßen, als ich versucht habe, eine bessere / protokollierte Ausgabe von zu erhalten du -sh $data_path. Ich habe das hier gefundene Muster "while command, do sleep" verwendet, aber ein komplexes AWK, um die gewünschte Ausgabe zu erhalten.

while du -sh $data_path; do sleep 1; done | awk '
$1 != size {
    size=$1;
    path=$2;
    time=systime();
    seconds=time-prevtime;
    if(seconds < 1000000000){
        seconds=seconds" seconds"
    }else{
        seconds=""
    }
    print size, path, strftime("%m/%d/%Y@%H:%M:%S", time), seconds; 
    prevtime=time
}'

Ich habe das eigentlich als Oneliner gemacht, weshalb es Semikolons gibt. Aber um es lesbar zu machen, habe ich es ausgebrochen. Die Ausgabe sieht folgendermaßen aus:

502G /var/lib/cassandra/dump/ 05/22/2018@04:46:17
503G /var/lib/cassandra/dump/ 05/22/2018@04:46:59 42 seconds
504G /var/lib/cassandra/dump/ 05/22/2018@04:47:57 58 seconds
505G /var/lib/cassandra/dump/ 05/22/2018@04:48:55 58 seconds
506G /var/lib/cassandra/dump/ 05/22/2018@04:49:53 58 seconds
507G /var/lib/cassandra/dump/ 05/22/2018@04:50:50 57 seconds
508G /var/lib/cassandra/dump/ 05/22/2018@04:51:46 56 seconds
509G /var/lib/cassandra/dump/ 05/22/2018@04:52:44 58 seconds
510G /var/lib/cassandra/dump/ 05/22/2018@04:53:41 57 seconds
Bruno Bronosky
quelle
0

Sie können ein Skript erstellen, das dies für Sie erledigt. Ich rief meine an keep(mach weiter) und legte sie auf den binWeg.

Das ist mein Drehbuch:

#!/bin/bash
echo "Repeating command $* every second"
while sleep 1; do
    "$@"
done
Alexandre Santos
quelle
1
Sie sollten verwenden "$@", um den Befehl (Argumente) anstatt ohne Anführungszeichen auszuführen $*. Auf diese Weise behält die Shell Argumente in Anführungszeichen usw. so bei, wie es der Benutzer erwarten würde. FTFY.
Roaima