Ist das in grep
einem kontinuierlichen Stream möglich?
Was ich meine, ist eine Art tail -f <file>
Befehl, aber mit grep
auf der Ausgabe, um nur die Zeilen zu behalten, die mich interessieren.
Ich habe es versucht, tail -f <file> | grep pattern
aber es scheint, dass grep
es nur ausgeführt werden kann, wenn es tail
fertig ist, das heißt nie.
tail -f file
funktioniert (ich sehe die neue Ausgabe in Echtzeit)Antworten:
Aktivieren Sie den
grep
Zeilenpuffermodus, wenn Sie BSD grep verwenden (FreeBSD, Mac OS X usw.).Sie müssen dies nicht für GNU grep tun (wird unter so ziemlich jedem Linux verwendet), da es standardmäßig geleert wird (YMMV für andere Unix-Likes wie SmartOS, AIX oder QNX).
quelle
strace
. Ohne das--line-buffered
wird es nicht funktionieren.tail -f | grep
und--line-buffered
löse es für mich (unter Ubuntu 14.04, GNU grep Version 2.16). Wo ist die Logik "Zeilenpufferung verwenden, wenn stdout eine tty ist" implementiert? In git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
wird nur durch das Argument Parser.--line-buffered
bekomme ich keine Ausgabe. Nach dem Testen sieht es jedoch so aus, als ob GNU grep das tut, was Sie beschreiben. Wie bei den meisten Unix-Dingen hängt dies von der Implementierung Ihrer Plattform ab. Da in der Frage keine Plattform angegeben wurde, scheinen Ihre Informationen falsch zu sein. Nachdem Sie den Code für BSD grep überprüft und mit GNU grep verglichen haben, wird das Verhalten definitiv durch die Option --line-buffered gesteuert. Es ist nur so, dass standardmäßig nur GNU grep gelöscht wird.Ich benutze das die
tail -f <file> | grep <pattern>
ganze Zeit.Es wird warten, bis grep errötet, nicht bis es beendet ist (ich benutze Ubuntu).
quelle
Ich denke, dass Ihr Problem darin besteht, dass grep eine gewisse Ausgabepufferung verwendet. Versuchen
Dadurch wird der Ausgabepuffermodus von grep auf ungepuffert gesetzt.
quelle
grep
.unbuffer
(imexpect-dev
Paket auf debian) ist König . Also würde ich Unpuffer über stdbuf verwenden.top
mit Stdbuf und Unbuffer). Und es gibt wirklich keine "magische" Lösung: Unpuffer schlägt manchmal auch fehl, zum Beispiel verwendet awk eine andere Pufferimplementierung (stdbuf schlägt auch fehl).stdbuf
`Unbuffer und Stdio Buffering unter pixelbeat.org/programming/stdio_bufferingWenn Sie Übereinstimmungen in der gesamten Datei finden möchten (nicht nur im Endbereich) und möchten, dass diese übereinstimmen und auf neue Übereinstimmungen warten, funktioniert dies einwandfrei:
Das
-c +0
Flag gibt an, dass die Ausgabe0
bytes (-c
) am Anfang (+
) der Datei beginnen soll.quelle
In den meisten Fällen können Sie
tail -f /var/log/some.log |grep foo
und es wird gut funktionieren.Wenn Sie mehrere Greps für eine laufende Protokolldatei verwenden müssen und feststellen, dass Sie keine Ausgabe erhalten, müssen Sie den
--line-buffered
Schalter möglicherweise wie folgt in Ihre mittleren Greps stecken :quelle
Sie können diese Antwort als Verbesserung betrachten. Normalerweise verwende ich
-F ist besser, wenn die Datei gedreht wird (-f funktioniert nicht richtig, wenn die Datei gedreht wird)
-A und -B sind nützlich, um Linien unmittelbar vor und nach dem Auftreten des Musters abzurufen. Diese Blöcke werden zwischen gestrichelten Trennzeichen angezeigt
Aber für mich mache ich lieber Folgendes
Dies ist sehr nützlich, wenn Sie in gestreamten Protokollen suchen möchten. Ich meine, geh hin und her und schau tief
quelle
grep -C 3 <pattern>
, ersetzt -A <N> und -B <N>, wenn N gleich ist.Ich habe nicht gesehen, dass jemand meine übliche Anlaufstelle dafür angeboten hat:
Ich bevorzuge dies, da Sie jederzeit
ctrl + c
anhalten und durch die Datei navigieren und dann einfach drücken könnenshift + f
, um zur Live-Streaming-Suche zurückzukehren.quelle
sed wäre eine bessere Wahl ( Stream- Editor)
tail -n0 -f <file> | sed -n '/search string/p'
und wenn Sie möchten, dass der Befehl tail beendet wird, sobald Sie eine bestimmte Zeichenfolge gefunden haben:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
Offensichtlich ein Bashismus: $ BASHPID ist die Prozess-ID des Befehls tail. Der Befehl sed steht nach dem Ende in der Pipe, sodass die sed-Prozess-ID $ BASHPID + 1 lautet.
quelle
$BASHPID+1
) gestartete Prozess Ihnen gehört, ist in vielen Situationen falsch, und dies trägt nicht zur Lösung des Pufferproblems bei, nach dem das OP wahrscheinlich zu fragen versuchte. Insbesondere empfehlensed
übergrep
scheint , wie hier nur eine Frage der (fragwürdigen) bevorzugt. (Sie könnenp;q
Verhalten mit bekommen,grep -m 1
wenn das der Punkt ist, den Sie versuchen zu liefern.)--line-buffered
nicht. Ich verstehe das Minus 1 aufrichtig nicht.Ja, das wird tatsächlich gut funktionieren.
Grep
Die meisten Unix-Befehle werden zeilenweise für Streams ausgeführt. Jede Linie, die aus dem Schwanz kommt, wird analysiert und weitergeleitet, wenn sie übereinstimmt.quelle
grep
der letzte Befehl in der Rohrkette ist, verhält er sich wie von Ihnen erklärt. Wenn es sich jedoch in der Mitte befindet, werden jeweils ca. 8.000 Ausgaben gepuffert.Dieser eine Befehl funktioniert für mich (Suse):
Sammeln von Anmeldungen beim Mail-Service
quelle
Sie werden sicherlich nicht erfolgreich sein
wenn Sie "colortail" als Alias für tail verwenden, z. in bash
Sie können anhand des Typalias überprüfen, ob dies so etwas wie tail isan alias von ausgibt
colortail -n 30
. dann hast du deinen schuldigen :)Lösung:
Entfernen Sie den Alias mit
Stellen Sie sicher, dass Sie mit diesem Befehl die 'echte' Tail-Binärdatei verwenden
welches sollte etwas ausgeben wie:
und dann können Sie Ihren Befehl ausführen
Viel Glück.
quelle
Verwenden Sie awk (ein weiteres großartiges Bash-Dienstprogramm) anstelle von grep, wenn Sie die Option "Zeilenpuffer" nicht haben! Es wird kontinuierlich Ihre Daten vom Schwanz streamen.
So verwenden Sie grep
So würden Sie awk verwenden
quelle
{print $0}
redundant, da das Drucken die Standardaktion ist, wenn eine Bedingung erfüllt ist.)