Sie sollten verwenden sed
.
sed -n -e 45000000,45000100p -e 45000101q bigfile > savedlines
Dies bedeutet sed
, Zeilen 45000000-45000100 einschließlich zu drucken und in Zeile 45000101 zu beenden.
Ich habe ein Problem mit dem Anzeigen von Blöcken einer sehr großen Textdatei. Diese Datei (ca. 19 GB) ist offensichtlich zu groß, um sie auf herkömmliche Weise anzuzeigen.
Ich habe versucht head 1
und tail 1
( head -n 1
und tail -n 1
) mit beiden Befehlen, die auf verschiedene Weise miteinander verbunden sind (um ein Stück in der Mitte zu erreichen), ohne Glück. Mein Linux-Computer mit Ubuntu 9.10 kann diese Datei nicht verarbeiten.
Wie gehe ich mit dieser Datei um? Mein ultimatives Ziel ist es, die Linien 45000000 und 45000100 zu verbessern.
Sie sollten verwenden sed
.
sed -n -e 45000000,45000100p -e 45000101q bigfile > savedlines
Dies bedeutet sed
, Zeilen 45000000-45000100 einschließlich zu drucken und in Zeile 45000101 zu beenden.
Erstellen Sie eine MySQL-Datenbank mit einer einzelnen Tabelle, die ein einzelnes Feld enthält. Dann importieren Sie Ihre Datei in die Datenbank. Dies macht es sehr einfach, eine bestimmte Zeile nachzuschlagen.
Ich glaube nicht, dass irgendetwas anderes schneller sein könnte (wenn head
und tail
schon versagen). Am Ende muss die Anwendung, die Zeile n
suchen will, die gesamte Datei n
durchsuchen, bis sie Zeilenumbrüche gefunden hat. Ohne eine Art Nachschlagen (Zeilenindex zu Byte-Offset in Datei) kann keine bessere Leistung erzielt werden.
In Anbetracht dessen, wie einfach es ist, eine MySQL-Datenbank zu erstellen und Daten in diese Datenbank zu importieren, halte ich dies für einen gangbaren Ansatz.
So wird's gemacht:
DROP DATABASE IF EXISTS helperDb; CREATE DATABASE `helperDb`; CREATE TABLE `helperDb`.`helperTable`( `lineIndex` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `lineContent` MEDIUMTEXT, PRIMARY KEY (`lineIndex`) ); LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable (lineContent); SELECT lineContent FROM helperTable WHERE ( lineIndex > 45000000 AND lineIndex < 45000100 );
/tmp/my_large_file
wäre die Datei, die Sie lesen möchten.
Die korrekte Syntax zum Importieren einer Datei mit durch Tabulatorzeichen getrennten Werten in jeder Zeile lautet:
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable FIELDS TERMINATED BY '\n' (lineContent);
Ein weiterer großer Vorteil ist, dass Sie, wenn Sie sich später entscheiden, einen anderen Satz von Zeilen zu extrahieren, keine Stunden auf die Verarbeitung warten müssen (es sei denn, Sie löschen natürlich die Datenbank).
Zwei gute alte Werkzeuge für große Dateien sind join
und split
. Sie können die --lines=<number>
Option split with verwenden, um Dateien in mehrere Dateien bestimmter Größe zu schneiden.
Zum Beispiel split --lines=45000000 huge_file.txt
. Die resultierenden Teile würden in xa, xb usw. sein. Dann können Sie head
den Teil xb verwenden, der die gewünschten Zeilen enthalten würde. Sie können Dateien auch zu einer einzelnen großen Datei zusammenfügen.
Sie haben die richtigen Werkzeuge, verwenden sie jedoch falsch. Wie bereits beantwortet bei U & L über, tail -n +X file | head -n Y
(die Note +
) ist 10-15% schneller als sed
für Y - Leitungen an X. Starten und bequem, müssen Sie sich nicht explizit auf exit
das Verfahren, wie mit sed
.
tail liest und verwirft die ersten X-1-Zeilen (es gibt keine Möglichkeit, dies zu umgehen), dann werden die folgenden Zeilen gelesen und gedruckt. head liest und druckt die angeforderte Zeilenzahl und geht dann aus. Wenn der Kopf beendet wird, empfängt das Endstück ein SIGPIPE-Signal und stirbt, so dass es nicht mehr als die Größe einer Puffergröße (normalerweise einige Kilobytes) von Zeilen aus der Eingabedatei gelesen hat.