Wie greife ich einen zufälligen Abschnitt in der Mitte einer riesigen Datei?

1690
WilliamKF

Ich habe eine riesige Protokolldatei von etwa 3,5 GB und möchte in der Mitte von etwa 10 MB zufällige Abschnitte ausprobieren, um zu debuggen, was meine Anwendung tut.

Ich könnte Kopf- oder Endbefehle verwenden, um den Anfang oder das Ende der Datei zu ermitteln. Wie kann ich einen beliebigen Teil aus der Mitte der Datei ziehen? Ich denke, ich könnte so etwas tun, head -n 1.75GB | tail -n 10MBaber das scheint unbeholfen zu sein, und ich müsste Zeilennummern für den Mittelpunkt der Datei ermitteln, um 1,75 GB und 10 MB Zeilenzahlen zu erhalten.

2

3 Antworten auf die Frage

6
kmkkmk
$ dd if=big_file.bin skip=1750 ibs=1MB count=10 of=big_file.bin.part 

Vielleicht möchten Sie etwas Zeit damit verbringen, dd zu lesen und zu verstehen.

Da "dd" keine Zeilen kennt, möchten Sie möglicherweise die erste und die letzte zuschneiden, so dass nur vollständige Zeilen enthalten sind, zB: `dd ... | Kopf -n-1 | Schwanz -n + 2` oder mit `sed`:` dd ... | sed '1d; $ d'`. Thor vor 11 Jahren 0
4
user1278519

Sie können use tail verwenden, geben Sie jedoch einen Byte-Offset an.

tail -c +$START_BYTE $file | head -c $LENGTH > newfile

Auf diese Weise kann das Endstück direkt zum Startpunkt springen (ohne neue Zeilen zu zählen), und sobald der Kopf die richtige Länge hat, hört er auf zu laufen.

Schön. Dies funktioniert mit beliebigen Byte-Offsets und Größen, die `dd` nicht kann. Mike vor 9 Jahren 0
@ Mike Kann es nicht? (GNU) `dd` hat die Optionen { _bytes`. Oder Sie könnten einfach `dd bs = 1` machen, aber das ist vielleicht nicht sehr effizient. Karel Vlk vor 5 Jahren 0
1
Keith

Sie müssen nur ein kleines Programm schreiben, um nach einem beliebigen Punkt zu suchen und einige Zeilen zu lesen.

Ein Beispiel in Python (liest eine Zeile, kann aber geändert werden):

def get_random_line(): """Return a randomly selected line from a file.""" import random fo = open("/some/file.txt") try: point = random.randrange(fo.size) fo.seek(point) c = fo.read(1) while c != '\n' and fo.tell() > 0: fo.seek(-2, 1) c = fo.read(1) line = fo.readline().strip() finally: fo.close() return line