Der Versuch, ein Problem mit einem Server zu debuggen, und meine einzige Protokolldatei ist eine 20-GB-Protokolldatei (auch ohne Zeitstempel! Warum wird die System.out.println()
Protokollierung verwendet? In der Produktion?!)
Mit grep habe ich einen Bereich der Datei gefunden, den ich mir ansehen möchte, Zeile 347340107.
Anders als so etwas zu tun
head -<$LINENUM + 10> filename | tail -20
... was das head
Lesen der ersten 347 Millionen Zeilen der Protokolldatei erfordern würde. Gibt es einen schnellen und einfachen Befehl, mit dem die Zeilen 347340100 - 347340200 (zum Beispiel) an die Konsole ausgegeben werden?
Update Ich habe total vergessen, dass grep den Kontext um ein Match drucken kann ... das funktioniert gut. Vielen Dank!
Antworten:
mit GNU-grep könnte man einfach sagen
quelle
Ich habe zwei andere Lösungen gefunden, wenn Sie die Zeilennummer kennen, aber sonst nichts (kein grep möglich):
Angenommen, Sie benötigen die Zeilen 20 bis 40,
oder
quelle
41q
sed an , in der Zeile zu beenden41
.Methode 3 effizient bei großen Dateien
schnellster Weg, um bestimmte Linien anzuzeigen
quelle
Nein, gibt es nicht, Dateien sind nicht zeilenadressierbar.
Es gibt keine zeitkonstante Möglichkeit, den Zeilenanfang n in einer Textdatei zu finden . Sie müssen durch die Datei streamen und Zeilenumbrüche zählen.
Verwenden Sie das einfachste / schnellste Werkzeug, das Sie für die Arbeit benötigen. Für mich mit
head
macht viel mehr Sinn alsgrep
, da letztere ist viel komplizierter. Ich sage nicht "grep
ist langsam", das ist es wirklich nicht, aber ich wäre überrascht, wenn es schneller wäre alshead
in diesem Fall. Das wäre imhead
Grunde genommen ein Fehler .quelle
Wie wäre es mit:
Ich habe es nicht getestet, aber ich denke, das würde funktionieren.
quelle
Ich gehe lieber einfach in
less
und:43210
das Gleiche tunund solche Sachen.
Noch besser: schlagen v Drücken Sie, um an dieser Stelle mit der Bearbeitung zu beginnen (natürlich in vim!). Beachten Sie nun, dass
vim
die gleichen Tastenkombinationen vorhanden sind!quelle
Ich würde die Datei zuerst in einige kleinere wie diese aufteilen
und grep dann auf die resultierenden Dateien.
quelle
Sie können den
ex
Befehl verwenden, einen Standard-Unix-Editor (jetzt Teil von Vim), zeine einzelne Zeile anzeigen (zB 2.):
entsprechende sed-Syntax:
sed -n '2p' file.txt
Zeilenbereich (zB 2-5 Zeilen):
sed Syntax:
sed -n '2,5p' file.txt
von der angegebenen Zeile bis zum Ende (zB 5. bis zum Ende der Datei):
sed Syntax:
sed -n '2,$p' file.txt
mehrere Zeilenbereiche (z. B. 2-4 und 6-8 Zeilen):
sed Syntax:
sed -n '2,4p;6,8p' file.txt
Die oben genannten Befehle können mit der folgenden Testdatei getestet werden:
Erläuterung:
+
oder-c
gefolgt vom Befehl - Führen Sie den Befehl (vi / vim) aus, nachdem die Datei gelesen wurde.-s
- Silent-Modus, verwendet auch das aktuelle Terminal als Standardausgabe,q
gefolgt von-c
dem Befehl zum Beenden des Editors (hinzufügen!
, um das Beenden zu erzwingen, z-scq!
. B. ).quelle
Wenn Ihre Zeilennummer 100 zum Lesen ist
quelle
Bekommen
ack
Ubuntu / Debian installieren:
Dann renne:
Beispiel:
Von
$ man ack
:quelle
--lines
Parameter entfernt.sed muss auch die Daten lesen, um die Zeilen zu zählen. Die einzige Möglichkeit, eine Verknüpfung zu erstellen, besteht darin, dass die Datei einen Kontext / eine Reihenfolge enthält, mit der bzw. der gearbeitet werden soll. Wenn beispielsweise Protokollzeilen mit einer festen Breite für Uhrzeit / Datum usw. vorangestellt sind, können Sie das Dienstprogramm look unix verwenden, um die Dateien nach bestimmten Datums- / Uhrzeitangaben binär zu durchsuchen
quelle
Verwenden
Hier erhalten Sie die Zeilennummer, in der die Übereinstimmung stattgefunden hat.
Jetzt können Sie mit dem folgenden Befehl 100 Zeilen drucken
oder Sie können auch "sed" verwenden
quelle
Wenn
sed -e '1,N d; M q'
Sie die Zeilen N + 1 bis M drucken, ist dies wahrscheinlich etwas besser,grep -C
da nicht versucht wird, die Linien einem Muster zuzuordnen.quelle
-e
ist hier optional.Aufbauend auf der Antwort von Sklivvz ist hier eine nette Funktion, die man in eine
.bash_aliases
Datei einfügen kann . Es ist effizient bei großen Dateien, wenn Inhalte von der Vorderseite der Datei gedruckt werden.quelle
Gehen Sie folgendermaßen vor, um eine Zeile von a
<textfile>
by its anzuzeigen<line#>
:Wenn Sie eine leistungsfähigere Methode zum Anzeigen einer Reihe von Zeilen mit regulären Ausdrücken wünschen - ich werde nicht sagen, warum grep eine schlechte Idee dafür ist, sollte dies ziemlich offensichtlich sein -, zeigt Ihnen dieser einfache Ausdruck Ihre Reichweite in a Single Pass, was Sie wollen, wenn Sie mit ~ 20 GB Textdateien arbeiten:
(Tipp: Wenn Ihre Regex enthalten ist
/
, verwenden Siem!<regex>!
stattdessen etwas wie )Dies würde
<filename>
beginnend mit der übereinstimmenden Zeile<regex1>
bis (einschließlich) der übereinstimmenden Zeile ausgedruckt<regex2>
.Es braucht keinen Assistenten, um zu sehen, wie ein paar Änderungen es noch leistungsfähiger machen können.
Letzte Sache: Perl hat, da es eine ausgereifte Sprache ist, viele versteckte Verbesserungen, um Geschwindigkeit und Leistung zu fördern. In diesem Sinne ist dies die offensichtliche Wahl für einen solchen Vorgang, da er ursprünglich für die Verarbeitung großer Protokolldateien, Texte, Datenbanken usw. entwickelt wurde.
quelle
Sie könnten diesen Befehl versuchen:
quelle
Einfach mit Perl! Wenn Sie die Zeilen 1, 3 und 5 aus einer Datei abrufen möchten, sagen Sie / etc / passwd:
quelle
Ich bin überrascht, dass nur eine andere Antwort (von Ramana Reddy) vorgeschlagen hat, der Ausgabe Zeilennummern hinzuzufügen. Im Folgenden wird nach der erforderlichen Zeilennummer gesucht und die Ausgabe gefärbt.
quelle