Ich habe eine ziemlich große .msg-Datei im UIEE-Format formatiert.
$ wc -l big_db.msg
8726593 big_db.msg
Im Wesentlichen besteht die Datei aus Einträgen unterschiedlicher Länge, die ungefähr so aussehen:
UR|1
AA|Condon, Richard
TI|Prizzi's Family
CN|Collectable- Good/Good
MT|FICTION
PU|G.P. Putnam & Sons
DP|1986
ED|First Printing.
BD|Hard Cover
NT|0399132104
KE|MAFIA
KE|FICTION
PR|44.9
XA|4
XB|1
XC|BO
XD|S
UR|10
AA|Gariepy, Henry
TI|Portraits of Perseverance
CN|Good/No Jacket
MT|SOLD
PU|Victor Books
DP|1989
BD|Mass Market Paperback
NT|1989 tpb g 100 meditations from the Book of Job "This book...help you
NT| persevere through the struggles of your life..."
KE|Bible
KE|religion
KE|Job
KE|meditations
PR|28.4
XA|4
XB|5
XC|BO
XD|S
Dies ist ein Beispiel für zwei Einträge, die durch eine Leerzeile getrennt sind. Ich möchte diese große Datei in kleinere Dateien aufteilen, ohne einen Eintrag in zwei Dateien aufzuteilen.
Jeder einzelne Eintrag wird durch eine neue Zeile (eine vollständig leere Zeile) in der Datei getrennt. Ich möchte diese 8,7-Millionen-Zeilendatei in 15 Dateien aufteilen. Ich verstehe, dass split
es solche Tools gibt, aber ich bin mir nicht ganz sicher, wie ich die Datei aufteilen soll, sondern nur in einer neuen Zeile, damit ein einzelner Eintrag nicht in mehrere Dateien aufgeteilt wird.
text-processing
split
user2036066
quelle
quelle
csplit
existiert auch.|
(wieUR
,AA
,TI
) relevant für die Zählung von Dateien, auch exakt das gleiche sein?Antworten:
Hier ist eine Lösung, die funktionieren könnte:
Es funktioniert, indem der erste
sed
dassed
Skript des zweiten schreiben kann . Die zweitesed
erste sammelt alle Eingabezeilen, bis sie auf eine leere Zeile stößt. Anschließend werden alle Ausgabezeilen in eine Datei geschrieben. Der erstesed
schreibt ein Skript für den zweiten aus und weist ihn an, wo seine Ausgabe geschrieben werden soll. In meinem Testfall sah dieses Skript folgendermaßen aus:Ich habe es so getestet:
Dies lieferte mir eine Datei mit 6000 Zeilen, die so aussah:
... 1000 mal wiederholt.
Nach dem Ausführen des obigen Skripts:
AUSGABE
quelle
Mit dem Vorschlag von
csplit
:Aufteilung nach Zeilennummern
Beispiel
Angenommen, ich habe eine Datei mit 1000 Zeilen.
führt zu Dateien wie folgt:
Sie können die statische Einschränkung umgehen, dass die Anzahl der Wiederholungen angegeben werden muss, indem Sie die Anzahl anhand der Anzahl der Zeilen in Ihrer bestimmten Datei im Voraus vorberechnen.
Aufteilung anhand von Leerzeilen
Wenn Sie andererseits eine Datei einfach in leere Zeilen aufteilen möchten, die in der Datei enthalten sind, können Sie diese Version von verwenden
split
:Beispiel
Angenommen, ich habe oben 4 leere Zeilen hinzugefügt
file.txt
und die Datei erstelltfile2.txt
. Sie können sehen, dass sie wie folgt manuell hinzugefügt wurden:Das Obige zeigt, dass ich sie zwischen den entsprechenden Nummern in meiner Beispieldatei hinzugefügt habe. Wenn ich jetzt den
csplit
Befehl ausführe :Sie können sehen, dass ich jetzt 4 Dateien habe, die basierend auf der Leerzeile aufgeteilt wurden:
Verweise
quelle
Wenn Sie sich nicht um die Reihenfolge der Aufzeichnungen kümmern, können Sie Folgendes tun:
Andernfalls müssen Sie zuerst die Anzahl der Datensätze ermitteln, um zu wissen, wie viele in jede Ausgabedatei eingefügt werden sollen:
quelle
file.in
undfile.out
?Wenn Sie nur am Ende einer Zeile teilen möchten, sollten Sie dies mit der
-l
Option für tun könnensplit
.Wenn Sie auf einer leeren Zeile (
\n\n
) teilen möchten, würde ich dies in ksh tun. Ich habe es nicht getestet und es ist wahrscheinlich nicht ideal, aber etwas in dieser Richtung würde funktionieren:quelle
\n\n
denke ich.\n\n
, sondern nicht mitten in einer Linie. Er nennt eine neue Zeile eine leere Zeile.Versuchen
awk
quelle
Wenn Sie sich nicht um die Reihenfolge der Datensätze kümmern, sondern eine bestimmte Anzahl von Ausgabedateien erhalten möchten, ist Stephanes Antwort der richtige Weg. Ich habe jedoch das Gefühl, dass es Ihnen wichtiger sein könnte, eine Größe anzugeben, die jede Ausgabedatei nicht überschreiten sollte. Das macht es tatsächlich einfacher, weil Sie Ihre Eingabedatei lesen und Datensätze sammeln können, bis Sie diese Größe erreicht haben, und dann eine neue Ausgabedatei starten können. Wenn das für Sie funktioniert, können die meisten Programmiersprachen Ihre Aufgabe mit einem kurzen Skript erledigen. Hier ist eine awk-Implementierung:
Fügen Sie dies beispielsweise in eine Datei ein
program.awk
und führen Sie es so aus,awk -v maxlen=10000 -f program.awk big_db.msg
dass der Wert vonmaxlen
die meisten Bytes ist, die Sie in einer Datei benötigen. Standardmäßig werden 500 KB verwendet.Wenn Sie eine festgelegte Anzahl von Dateien erhalten möchten, ist es wahrscheinlich am einfachsten, die Größe Ihrer Eingabedatei durch die Anzahl der gewünschten Dateien zu teilen und dann ein bisschen zu dieser Anzahl hinzuzufügen, um sie zu erhalten
maxlen
. Um beispielsweise 15 Dateien aus Ihren 8726593-Bytes herauszuholen, dividieren Sie durch 15, um 581773 zu erhalten, und fügen Sie einige hinzu. Geben Sie also vielleichtmaxlen=590000
odermaxlen=600000
. Wenn Sie dies wiederholt tun möchten, können Sie das Programm dafür konfigurieren.quelle