Schwanz -f, aber mit Zeilennummern


21

Ich versuche zu sehen, wie oft innerhalb einer beliebigen Zeitspanne auf einem Remote-Server foo barangezeigt wird /var/log/foo.log, aber nichts, was ich bisher ausprobiert habe, hat funktioniert.

Ich habe bereits ein Timer-Skript, mit dem ich nachverfolgen kann /var/log/foo.log, wie lange es her ist, seit ich mit dem Tailing begonnen habe , und jetzt möchte ich nur noch wissen , wie oft die Tailing- foo barAusgabe aufgetreten ist.

Ich habe in Google gesucht, aber in den ersten 10 Ergebnisseiten nichts Passendes gefunden.

Folgendes habe ich mit frustrierenden Ergebnissen versucht:

## works on local machine, but doesn't work as expected on remote
tail -f /var/log/foo.log | grep foo\ bar | sed '='

## works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | cat -n -

##  works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | awk -F'\n' '{printf "[%d]> ", NR; print $1}'

Ich habe sogar versucht, ein Sed-Skript zu schreiben, das sich so verhält tail -f, aber ich habe damit fast keine Fortschritte gemacht.

HINWEIS

der Remote - Server ist eine ältere Version von coreutils ausgeführt wird , und Modernisierung ist eine Option, aber ist nicht in irgendeiner Weise die gewünschte Lösung.


2
Auf welche Weise funktioniert es nicht? Versuchen Sie die --line-bufferedOption zu grep. Odertail -f ... | awk '/foo bar/{print ++n, $0}'
Stéphane Chazelas

Warum funktioniert es nicht auf Remote? Beispiel:tail -f /var/log/log.log | awk '{ printf "[%d]> %s\n", NR+1 ,$0; fflush(stdout); }'

Antworten:


29
tail -f | nl

funktioniert bei mir und ist das erste, woran ich gedacht habe - das heißt, wenn Sie wirklich wollen, dass die Zeilen von 1 nummeriert werden und nicht mit der tatsächlichen Zeilennummer aus der Datei überwacht werden. Fügen Sie diese grepgegebenenfalls an der entsprechenden Stelle hinzu (entweder vorher oder nachher nl). Denken Sie jedoch daran, dass möglicherweise eine Pufferung auftritt. In meinem speziellen Fall grephat die --line-bufferedOption, aber nlpuffert seine Ausgabe und hat keine Option, um das auszuschalten. Daher tail | nl | grepfließt die Combo nicht wirklich gut.

Das gesagt,

tail -f | grep -n pattern

funktioniert auch bei mir Die Nummerierung beginnt wieder am Anfang des "Tailings" und nicht am Anfang der gesamten Protokolldatei.


Die Version von grep, die auf dem Server ausgeführt wird, hat keine -nOption.
Alexej Magura

es hat jedoch die lange möglichkeit --line-number: tail -f /var/log/foo.log | grep foo\ bar --line-numberfunktioniert!
Alexej Magura

1
Das ist interessant - ich habe POSIX als solches nicht überprüft, aber die GNU grep-Manpage sagt: -n wird von POSIX angegeben .
Peterph

16

Ich denke das ist besser ..

less -N +F <filepath>

2
Können Sie erklären, warum Sie es für besser halten?
Navigatron 18.11.15

Dies ist eine große Bearbeitung, ich mache es wieder rückgängig.
Adam Eberlin

3
Zeigt die Zeilennummer als Referenz für die gesamte Datei an. Schwanz -f | nl zeigt die Zeilennummer, wobei die erste Ausgabe von tail als Referenz genommen wird.
Rafaelvalle

Dies ist sehr praktisch und befasst sich mit dem Titel des OP , nicht jedoch mit dessen Frage . Sie wollten wissen, wie oft X in einer Datei vorkommt: P
Timmah

6

Sie können die Ausgabe auch an leiten less. Sie verfügt über eine Zeilennummernfunktion, mit -Nder Sie im Protokoll vor- und zurückblättern können.

$ tail -f /var/log/foo.log | less -N

Beispiel

  1 Jan 17 22:11:58 greeneggs fprintd[4323]: ** Message: entering main loop
  2 Jan 17 22:12:01 greeneggs su: (to root) saml on pts/5
  3 Jan 17 22:12:28 greeneggs fprintd[4323]: ** Message: No devices in use, exit
  4 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Git | personal_repo | Checking for remote changes...
  5 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git rev-parse HEAD
  6 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git ls-remote --heads --exit-code "ssh://sam@sparkleshare.jake      
  6 8us.org/home/sam/SparkleShare/personal_repo.git" master
  7 Jan 17 22:12:58 greeneggs gnome-session[1876]: X11 forwarding request failed on channel 1
  8 Jan 17 22:12:58 greeneggs gnome-session[1876]: 22:12:58 | Git | personal_repo | No remote changes, local+remote: 532213be48cce3b93cb177d409faa      
  8 03b71d0cfa5
  9 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Pinging tcp://notifications.sparkleshare.org:443/
 10 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Received pong from tcp://notifications.sparkleshare.org:443/

HINWEIS: Beachten Sie die Ausgabe. Möglicherweise gefällt Ihnen diese Funktion nicht, es werden jedoch lange Zeilen benötigt, um sie zu zerschneiden, sodass sie in der nächsten Zeile fortgesetzt werden, wobei jedoch die entsprechende Zeilennummer beibehalten wird. Ich finde diese Funktion von unschätzbarem Wert beim Parsen von Protokolldateien, die breit sind! Sie können den Effekt dieser Funktion in den Zeilen 6 und 8 sehen .


Das ist unklar. Wo ist der Dateiname angegeben? Es sollte klargestellt werden, dass die Ausgabe von 1 beginnend mit den letzten 10 Zeilen des Dateinamens nummeriert ist, da dies das Standardverhalten von ist tail. Bei den langen Zeilen wird dieses Verhalten innerhalb von lessusing umgeschaltet -S.
ILMostro_7

2

Um neue Zeilen nur in der Protokolldatei zu erfassen, wie sie mit ihrer Zeilennummer geliefert werden, können Sie Folgendes tun:

{
  initial_lines=$(wc -l)
  tail -n +1 -f | awk -v NR="$initial_lines" '/pattern/{print NR": "$0}'
} < file.log

(Mit mawkmöchten Sie die -WinteractiveOption hinzufügen , um die Eingabepufferung (!) zu verhindern ).

wc -lLiest die Zeilen , die schon da waren und zählt sie (die Zeilenumbrüche, was bedeutet, dass es immer noch funktioniert, auch wenn die letzte Zeile noch nicht voll ist), und dann geben wir tail -fden Rest (beginnend mit dem wcAufhören des Lesens) an und geben awkdie Zeilennummer an der erste, den es sieht.


Die Wahl ldes Variablennamens ließ mich die Augen auf $ 1 blinzeln und dachte, es sei $1^^ (aber da ich Sie kenne (und zu 100% vertraue), habe ich die Wahrheit noch einmal gelesen und gesehen). Nur aus Neugier: Um eine "Race Condition" zwischen dem wc -lund dem zu vermeiden tail -f(wenn die Datei schnell wächst, kann man einige Zeilen verwerfen und die NR beginnt mit der falschen Nummer), $lkönnen stattdessen Zeilen übersprungen werden? (und welche Grenze gibt es -nin posix & in gnu zum Schwanz ?). Vielleicht mit einer temporären Zwischendatei?
Olivier Dulac

@OlivierDulac tail -n +1(liest irgendetwas von der Startposition) spricht die Bedenken bezüglich der Rennbedingungen an. Die Zeilen, die sich zum Zeitpunkt der wc -lBeendigung nicht in der Datei befanden , werden von der exakten Position gelesen, an der sie sich befanden wc. Somit hat NR die richtige Position, unabhängig davon, wie viele Zeilen zwischen wcEnde und tailAnfang geschrieben wurden. Wenn Sie aufgefordert werden tail, von einer Position relativ zum Ende der Datei zu beginnen, treten Probleme auf.
Stéphane Chazelas

oh, interresting: in der tat häufen sich die daten in stdin an, während nichts sie liest (zwischen dem ende des wc bis zum anfang des kopfes) ... ich hätte das realisieren sollen. Danke. Jetzt verstehe ich, warum Sie "<Datei". klug, wie immer :)
Olivier Dulac

1
@OlivierDulac, über Einschränkungen (die nicht gelten für tail -n +1 ), für reguläre Dateien haben die meisten Implementierungen keine, da sie vom Ende und seekzurück beginnen können, bis sie die n-te Zeile finden, ohne mehr als einen Buf-Wert speichern zu müssen von Daten im Speicher. Bei nicht suchbaren Eingaben können Sie an Grenzen stoßen. Für POSIX müssen Implementierungen in der Lage sein, mindestens 10 x LINE_MAX-Bytes zu speichern (LINE_MAX muss mindestens 2048 sein). GNU Tail hat keine andere Grenze als Speicher AFAIK
Stéphane Chazelas

0

Wenn Sie von Anfang an nummerieren möchten, müssen Sie grep -n auf alle Zeilen anwenden.

 tail -f -n100000000 filename.log | grep -n '' 

Wenn Sie dann nur die letzten 10 anzeigen wollten, hätte ich gedacht, Sie könnten die Datei erneut anpassen:

 tail -f -n100000000 filename.log | grep -n '' | tail -n10

Der erste ist praktisch, zeigt aber zu viel Leistung. Ich weiß nicht, warum der zweite nicht funktioniert.


Schwanz hat keine "alle Zeilen anzeigen", daher meine 100000000
Martin Cleaver

1
tail -n +1 -fvon Anfang an beschatten.
Stéphane Chazelas

1
Die zweite funktioniert nicht, weil die am weitesten rechts stehende tailPerson erst dann etwas ausgeben kann, wenn sie die letzte Zeile ihrer Eingabe gesehen hat (wie würde sie wissen, welche die zehntletzte Zeile ist?), Was niemals passieren wird, da tail -fniemals aufhört.
Stéphane Chazelas

-1

Der Befehl cat -n [filename] | tailwird eine schnelle Zählung und Anzeige der neuesten Datensätze erhalten, wenn Sie danach suchen.

Das -f Schalter hält ihn bis zum Escape-Vorgang an - was in Ihrem Szenario wirklich nicht zutreffend oder redundant klingt.

wc -l [filename] wird eine Zählung der Linien im Ziel erhalten

wc -l [filenameprefix]* zählt alle Zeilen in allen Dateien, die mit dem Muster übereinstimmen, und gibt am Ende sogar eine Gesamtsumme aus.

Vollständigeres Detail kann zu vollständigeren Antworten führen.


-1

Es ist das Argument noder --lines(wird etwas anders verwendet, siehe unten):

$ tail -f -n 25 /path/to/file.txt

$ tail -f --lines=25 /path/to/file.txt

Siehe auch die Hilfe:

$ tail --help

Das OP möchte Zeilennummern, keine Zeilennummern.
robbat2
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.