Anwendungsfall: Sie haben eine mehrere GB große Protokolldatei für eine ganze Woche und müssen beispielsweise nach etwas suchen, das am Samstag passiert ist grep
. Sie gehen davon aus, dass Sie die Verarbeitungszeit mehr als halbieren können, wenn Sie die Suche in der Mitte der Datei starten (da definitiv nicht der gesamte Rest der Datei verarbeitet werden muss), ohne dass relevante Daten übersprungen werden. Ist das möglich?
Antwort1
Vorausgesetzt, Ihre Daten sind in chronologischer Reihenfolge:
- Ermitteln Sie die Größe der Datei, indem Sie bis zum Ende suchen und
ftell()
; ausführen. - Teilen Sie dieses Ergebnis durch 2;
- Verwenden Sie es
fseek()
, um zu diesem Ort zu suchen; - Suchen Sie durch einmaligen Aufruf zum Anfang der nächsten Zeile
getline()
. - Verwenden Sie
strptime()
, um herauszufinden, welches Datum Sie gerade haben; - Führen Sie eine binäre Suche durch und wiederholen Sie die Schritte 4 und 5, bis Sie die gewünschte Zeile finden.
Antwort2
Sie könnten dd
Folgendes verwenden:
dd if=log skip=xK bs=1M
Dadurch werden x * 1024 Blöcke der Größe 1M (2^20) übersprungen. dd(1)
Weitere Informationen zur Handhabung von Einheiten finden Sie unter.
Wenn Sie die binäre Suche automatisieren möchten (vorausgesetzt Ihr Protokoll hat das übliche Format, <date> [data]
an das Sie die Ausgabe weiterleiten können) head -n 2
, überprüfen Sie das Datum am Anfang deszweiteZeile (die - unter der vernünftigen Annahme „normalerweise“ langer Zeilen - vollständig sein wird) und entscheiden Sie, welche Hälfte Sie möchten.
Antwort3
Ermitteln Sie die Dateigröße und dividieren Sie sie durch 2. Dividieren Sie das Ergebnis durch 1024, um KiB zu erhalten. (Oder 1024*1024, um MiB usw. zu erhalten.)
((fs = $(stat -c %s logfile) / 2 / 1024))
Überspringen und suchen
dd if=logfile bs=1024 skip=$fs | grep blahblah
Sie können dies weiter ausführen, wenn die Protokolldateisehrim Einklang mit der Datenmenge pro Tag, indem Sie einen count=
Wert zu hinzufügen dd
.
((cnt = $(stat -c %s logfile) / 5 / 1024))
dd if=logfile bs=1024 skip=$fs count=$cnt | grep blahblah
cnt * 1024
Dadurch werden Datenbytes an den Offset -Bytes weitergeleitet fs * 1024
.
Fassen Sie alles in einem Skript zusammen und führen Sie die Weiterleitung außerhalb des Skripts zu grep, einer temporären Datei oder was auch immer Sie möchten durch.
Antwort4
Es ist nicht ganz klar, was Sie genau tun möchten und was Sie mit meinem „Prozess“ meinen. Für große Dateien ist mein bevorzugtes interaktives Programm less
. Es verarbeitet große Dateien problemlos. Es kann auch zu einem bestimmten Prozentsatz springen, z. B. mit 30%
. Darüber hinaus können Sie mit /
und suchen ?
.