26705
13.02.2007, aktualisiert am 14.02.2007
22493
12
0
Textdatei mit 300.000 Zeilen splitten
Moin,
kennt jemand eine Möglichkeit eine Textdatei mit über 300000 Zeilen in nen Haufen kleinere Textdateien mit 2500 Zeilen aufzuteilen?
Hab mich schon an ner Batch probiert aus nem Thread hier probiert (Logfile letzten Zeilen in Txt File mit Batch).
Das funktioniert auch wunderbar, aber nur bis ca. 4000 Zeilen, dann bricht die Batch ab.
Hat jemand noch irgendeine Idee?
Habe hier zur Zeit leider nur Win XP zur Verfügung...
kennt jemand eine Möglichkeit eine Textdatei mit über 300000 Zeilen in nen Haufen kleinere Textdateien mit 2500 Zeilen aufzuteilen?
Hab mich schon an ner Batch probiert aus nem Thread hier probiert (Logfile letzten Zeilen in Txt File mit Batch).
Das funktioniert auch wunderbar, aber nur bis ca. 4000 Zeilen, dann bricht die Batch ab.
Hat jemand noch irgendeine Idee?
Habe hier zur Zeit leider nur Win XP zur Verfügung...
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 51534
Url: https://administrator.de/contentid/51534
Ausgedruckt am: 16.11.2024 um 01:11 Uhr
12 Kommentare
Neuester Kommentar
Hallo SeppelCeh!
Bei der Lösung per Batch gibt es öfters Probleme mit Sonderzeichen wie "&" oder ">", etc, daher eine VB-Script-Variante:
Aufruf mit
Alternativ kannst Du auch einfach die Textdatei auf das Script ziehen, dann werden Teildateien mit je 2500 Zeilen erzeugt (siehe "lMaxLine = 2500").
Die Teildateien werden jeweils im Ordner der ursprünglichen Textdatei mit dem gleichen Dateityp abgelegt. Die restliche Namensgebung findet in der Zeile "sOutName = sPath & "\Part_"" statt - "Part_" kannst Du auf Wunsch ersatzlos streichen, der "\" wird benötigt.
In der aktuellen Fassung ist die Anzahl der Teildateien auf 999 beschränkt, durch Änderung der Zeile "iFileNr=1001" auf einen Wert 10001 erhältst Du 4-stellige Dateinamen, also bis zu 9999 Dateien.
Grüße
bastla
Bei der Lösung per Batch gibt es öfters Probleme mit Sonderzeichen wie "&" oder ">", etc, daher eine VB-Script-Variante:
'SplitTextFile.vbs
sInFile = WScript.Arguments(0)
If WScript.Arguments.Count < 2 Then
lMaxLine = 2500
Else
lMaxLine = CLng(WScript.Arguments(1))
End If
Set fso = Wscript.CreateObject("Scripting.FileSystemObject")
sPath = fso.GetFile(sInFile).Path
sPath = Left(sPath, InstrRev(sPath, "\") - 1)
sOutName = sPath & "\Part_"
If InstrRev(sInFile, ".") Then
sOutType = Mid(sInFile, InstrRev(sInFile, "."))
End If
lLineNr=0
iFileNr=1001
Set oOut = fso.OpenTextFile(sOutName & Mid(CStr(iFileNr),2) & sOutType, 2, True)
Set oIn = fso.OpenTextFile(sInFile, 1)
Do While Not oIn.AtEndOfStream
oOut.WriteLine oIn.ReadLine
lLineNr = lLineNr + 1
If lLineNr >= lMaxLine Then
lLineNr = 0
oOut.Close
iFileNr = iFileNr + 1
Set oOut = fso.OpenTextFile(sOutName & Mid(CStr(iFileNr),2) & sOutType, 2, True)
End If
Loop
oIn.Close
oOut.Close
WScript.Echo "Done."
SplitTextFile.vbs Textdatei ZeilenJeDatei
Die Teildateien werden jeweils im Ordner der ursprünglichen Textdatei mit dem gleichen Dateityp abgelegt. Die restliche Namensgebung findet in der Zeile "sOutName = sPath & "\Part_"" statt - "Part_" kannst Du auf Wunsch ersatzlos streichen, der "\" wird benötigt.
In der aktuellen Fassung ist die Anzahl der Teildateien auf 999 beschränkt, durch Änderung der Zeile "iFileNr=1001" auf einen Wert 10001 erhältst Du 4-stellige Dateinamen, also bis zu 9999 Dateien.
Grüße
bastla
Hallo zusammen!
Beruflich bedingt kenne ich dieses Forum schon längere Zeit und bin ausgesprochen dankbar dafür, da es mir bereits des Öfteren zu einem Problem entweder einen guten Ansatz oder sogar die Lösung geliefert hat. Da ich diesmal jedoch keine Antwort auf meine Frage gefunden habe, habe ich mich nun registriert und hoffe, dass mir eventuell jemand weiterhelfen kann...
Hier nun mein Problem: Über die Exportfunktion in DATEV Kanzlei-Rechnungswesen habe ich zunächst eine CSV-Datei mit Debitorenstammdaten eines Mandanten erstellt. Leider kann ich diese nicht weiterverarbeiten, da das Programm für die Folgebearbeitung eine Größenbeschränkung von 2 MB hat. Meine Export-Datei hat jedoch eine Dateigröße von 20 MB.
Eine Anfrage bei der DATEV-Hotline brachte mich nicht wirklich weiter, da man mir lediglich vorschlug, die Datei einfach händisch zu splitten. Da die Stammdaten jedoch einmal pro Woche über diesen Weg aktualisiert werden müssen, wäre das nicht wirklich praktikabel...
So gesehen hilft mir die von Bastla programmierte Lösung in gewisser Weise weiter, allerdings kommen bei der Verarbeitung durch das obige VB-Script am Ende auch wieder gesplittete CSV-Dateien mit der Endung .csv raus. Zur weiteren Verarbeitung brauche ich jedoch CSV-Dateien mit der Endung .txt. Darüber hinaus habe ich in der Ursprungsdatei am Anfang auch eine feste Anzahl an Zeilen, die als Header dienen und die zur korrekten Verarbeitung in den gesplitteten Dateien jeweils am Anfang vorhanden sein müssten.
Leider gehen meine VBS-Programmierkenntnisse so ziemlich gen Null, so dass ich nun vor einem für mich "unlösbaren" Problem stehe. Daher hoffe ich nun, dass sich jemand meines Problems annimmt und mir damit sehr weiterhelfen würde...
Vielen Dank im Voraus!
Grüße
Celimos
Beruflich bedingt kenne ich dieses Forum schon längere Zeit und bin ausgesprochen dankbar dafür, da es mir bereits des Öfteren zu einem Problem entweder einen guten Ansatz oder sogar die Lösung geliefert hat. Da ich diesmal jedoch keine Antwort auf meine Frage gefunden habe, habe ich mich nun registriert und hoffe, dass mir eventuell jemand weiterhelfen kann...
Hier nun mein Problem: Über die Exportfunktion in DATEV Kanzlei-Rechnungswesen habe ich zunächst eine CSV-Datei mit Debitorenstammdaten eines Mandanten erstellt. Leider kann ich diese nicht weiterverarbeiten, da das Programm für die Folgebearbeitung eine Größenbeschränkung von 2 MB hat. Meine Export-Datei hat jedoch eine Dateigröße von 20 MB.
Eine Anfrage bei der DATEV-Hotline brachte mich nicht wirklich weiter, da man mir lediglich vorschlug, die Datei einfach händisch zu splitten. Da die Stammdaten jedoch einmal pro Woche über diesen Weg aktualisiert werden müssen, wäre das nicht wirklich praktikabel...
So gesehen hilft mir die von Bastla programmierte Lösung in gewisser Weise weiter, allerdings kommen bei der Verarbeitung durch das obige VB-Script am Ende auch wieder gesplittete CSV-Dateien mit der Endung .csv raus. Zur weiteren Verarbeitung brauche ich jedoch CSV-Dateien mit der Endung .txt. Darüber hinaus habe ich in der Ursprungsdatei am Anfang auch eine feste Anzahl an Zeilen, die als Header dienen und die zur korrekten Verarbeitung in den gesplitteten Dateien jeweils am Anfang vorhanden sein müssten.
Leider gehen meine VBS-Programmierkenntnisse so ziemlich gen Null, so dass ich nun vor einem für mich "unlösbaren" Problem stehe. Daher hoffe ich nun, dass sich jemand meines Problems annimmt und mir damit sehr weiterhelfen würde...
Vielen Dank im Voraus!
Grüße
Celimos
Hallo Celimos und willkommen als Mitglied!
Eine an Deine Wünsche angepasste (und etwas aktualisierte sow wie oberflächlich getestete) Fassung des Scripts könnte etwa so aussehen:
Der Aufruf erfolgt mit
Alternativ können auch in den Zeilen 2 bis 4 anstelle von "
Die Zieldateien werden im Ordner der Quelldatei (siehe Zeile 9 - dort könnte auch ersatzweise ein anderer Pfad festgelegt werden) mit den Namen "Part_###.txt" erstellt (siehe dazu Zeilen 5 und 6), wobei die Stellenanzahl der laufenden Nummer an die Anzahl der Dateien angepasst wird: Entstehen etwa 79 Dateien, lauten deren Namen "Part_01.txt" bis "Part_79.txt", werden es 1235 Dateien, werden diese "Part_0001.txt" bis "Part_1235.txt" benannt.
Jede Zieldatei enthält die angegebene Anzahl von Kopfzeilen + die angegebene Anzahl von Datenzeilen.
Grüße
bastla
[Edit] Korrektur der Berechnung (s.u.) in Zeile 14 (jetzt 16) und Umstellung auf Angabe eines Zielordners als 4. Aufrufparameter [/Edit]
Eine an Deine Wünsche angepasste (und etwas aktualisierte sow wie oberflächlich getestete) Fassung des Scripts könnte etwa so aussehen:
'SplitTextFile.vbs
sInFile = WScript.Arguments(0)
lDataLines = CLng(WScript.Arguments(1))
lHeaderLines = CLng(WScript.Arguments(2))
sOutFolder = WScript.Arguments(3) 'kann natürlich auch hier fix eingetragen werden, zB: sOutFolder = "Parts"
sOutFileName = "Part_"
sOutType = ".txt"
Set fso = CreateObject("Scripting.FileSystemObject")
sOutPath = fso.GetParentFolderName(fso.GetFile(sInFile).Path) & "\" & sOutFolder
If Not fso.FolderExists(sOutPath) Then fso.CreateFolder(sOutPath) 'Zielordner bei Bedarf erzeugen
sOutName = sOutPath & "\" & sOutFileName 'Zielpfad inkl konstantem Namensanteil erstellen
aText = Split(fso.OpenTextFile(sInFile).ReadAll, vbCrLf) 'gesamten Inhalt in Array einlesen
lLines = (UBound(aText))'höchste Zeilennummer
iFiles = Int((lLines + 1) / lDataLines + .99999) 'Anzahl Zieldateien
iDigits = Int(Log(iFiles) / Log(10)) + 1 'Stellenanzahl für Dateinummer
lLineNr = lHeaderLines '1. Datenzeile (nullbasiert) der Quelldatei
lFileNr = 1000001
For i = 1 To iFiles 'Schleife für Zieldateien
Set oOut = fso.CreateTextFile(sOutName & Right(CStr(lFileNr), iDigits) & sOutType) 'Zieldatei mit lfd Nummer erstellen
'Ausgabe Kopfzeilen
For j = 1 To lHeaderLines
oOut.WriteLine (aText(j - 1))
Next
'Ausgabe Zeilen in gewünschter Anzahl
For j = 1 To lDataLines
If lLineNr > lLines Then Exit For 'letzte Datei enthält uU weniger als lDataLines Zeilen
oOut.WriteLine (aText(lLineNr)) 'Zeile schreiben
lLineNr = lLineNr + 1 'Quelldatei-Zeilennummer erhöhen
Next
oOut.Close 'Zieldatei schließen
lFileNr = lFileNr + 1 'ldf Nummer für Zieldatei erhöhen
Next
WScript.Echo "Done."
SplitTextFile.vbs CSV-Datei Datenzeilenanzahl Kopfzeilenanzahl
WScriptArguments(x)
" die gewünschten Werte in das Script eingetragen werden - für die Quelldatei würde das so aussehen:sInFile = "D:\Pfad zur Datei\Datei.csv"
Jede Zieldatei enthält die angegebene Anzahl von Kopfzeilen + die angegebene Anzahl von Datenzeilen.
Grüße
bastla
[Edit] Korrektur der Berechnung (s.u.) in Zeile 14 (jetzt 16) und Umstellung auf Angabe eines Zielordners als 4. Aufrufparameter [/Edit]
Hallo Bastla!
zunächst einmal ganz herzlichen Dank, dass Du mir so schnell eine Lösung "gezaubert" hast! Damit hast Du mir wirklich enorm viel Zeit und Nerven erspart.
Leider wollte das Script jedoch auf Anhieb nicht ganz funktionieren, aber durch Deine Kommentare und Erläuterungen glaube ich auch ohne große VB-Scriptkenntnisse dahintergekommen zu sein, wo sich der "Fehlerteufel" eingeschichen hat. Wenn ich das richtig sehe, müsste das Problem in Zeile 14 bei der Zahl hinter der Variable "lDataLines" liegen, denn damit rundet er ja den Integer-Wert auf die nächst höhere ganze Zahl auf - richtig? Somit müsste die Zeile dann sicher wie folgt lauten:
Geäußert hat sich das Problem dadurch, dass bei der Verarbeitung nur Dateien erzeugt wurden, die die maximal definierte Zeichenanzahl enthielten. Da jedoch die Aufsplittung der Gesamtzeilenanzahl nur im Idealfall genau aufgeht und bei einer Gegenprüfung mit der Ursprungsdatei zudem ein paar Datensätze gefehlt haben, konnte ich den Fehler hierauf eingrenzen.
Nach der Korrektur arbeitet das Script jetzt an sich einwandfrei, allerdings hätte ich noch eine "kleine" Bitte: Sofern es für Dich nicht zu viel Aufwand bedeutet und Du das ganze Script nicht noch mal komplett umschreiben musst, würde ich gerne die gesplitteten Dateien zusätzlich in einen Ordner packen, da es sonst bei der Verwendung auf dem Desktop und einer größeren Anzahl an gesplitteten Dateien schnell unübersichtlich wird. Besondes schön wäre es natürlich, wenn diese Funktion wieder so "flexibel" aufgebaut wäre, wie das restliche Script, so dass es möglich ist, oben in der Datei den Ordnernnamen zu definieren und er mir dann an der Stelle, an der sich das Script befindet, einfach die Dateien in den genannten Ordner packt.
Auch hieran habe ich mich heute bereits längere Zeit erfolglos versucht und wäre ausgesprochen dankbar, wenn Du mir nochmals unter die Arme greifen könntest.
Grüße
Celimos
zunächst einmal ganz herzlichen Dank, dass Du mir so schnell eine Lösung "gezaubert" hast! Damit hast Du mir wirklich enorm viel Zeit und Nerven erspart.
Leider wollte das Script jedoch auf Anhieb nicht ganz funktionieren, aber durch Deine Kommentare und Erläuterungen glaube ich auch ohne große VB-Scriptkenntnisse dahintergekommen zu sein, wo sich der "Fehlerteufel" eingeschichen hat. Wenn ich das richtig sehe, müsste das Problem in Zeile 14 bei der Zahl hinter der Variable "lDataLines" liegen, denn damit rundet er ja den Integer-Wert auf die nächst höhere ganze Zahl auf - richtig? Somit müsste die Zeile dann sicher wie folgt lauten:
iFiles = Int((lLines + 1) / lDataLines + 1) 'Anzahl Zieldateien
Geäußert hat sich das Problem dadurch, dass bei der Verarbeitung nur Dateien erzeugt wurden, die die maximal definierte Zeichenanzahl enthielten. Da jedoch die Aufsplittung der Gesamtzeilenanzahl nur im Idealfall genau aufgeht und bei einer Gegenprüfung mit der Ursprungsdatei zudem ein paar Datensätze gefehlt haben, konnte ich den Fehler hierauf eingrenzen.
Nach der Korrektur arbeitet das Script jetzt an sich einwandfrei, allerdings hätte ich noch eine "kleine" Bitte: Sofern es für Dich nicht zu viel Aufwand bedeutet und Du das ganze Script nicht noch mal komplett umschreiben musst, würde ich gerne die gesplitteten Dateien zusätzlich in einen Ordner packen, da es sonst bei der Verwendung auf dem Desktop und einer größeren Anzahl an gesplitteten Dateien schnell unübersichtlich wird. Besondes schön wäre es natürlich, wenn diese Funktion wieder so "flexibel" aufgebaut wäre, wie das restliche Script, so dass es möglich ist, oben in der Datei den Ordnernnamen zu definieren und er mir dann an der Stelle, an der sich das Script befindet, einfach die Dateien in den genannten Ordner packt.
Auch hieran habe ich mich heute bereits längere Zeit erfolglos versucht und wäre ausgesprochen dankbar, wenn Du mir nochmals unter die Arme greifen könntest.
Grüße
Celimos
Hallo Celimos!
Mit dem Fehler in Zeile 14 (das Problem war nicht das Aufrunden auf die nächste ganze Zahl, sondern das kaufmännische Runden nach der 4/5-Regel, wodurch dann eben öfter nicht aufgerundet wird) hast Du recht, die Korrektur ist ganz knapp an der Optimallösung vorbei - es sollte nämlich nur .99999 addiert werden, damit nicht für den Fall, dass es genau ein Vielfaches der gewünschten Zeilenanzahl gibt, eine Datei zuviel (würde dann nur die Kopfzeilen enthalten) erzeugt wird ...
Ich korrigiere das oben noch und baue auch die Verwendung eines (als 4. Parameter beim Scriptaufruf) vorgegebenen Zielordners ein (den Hinweis auf die Zeile 9 - ist jetzt Zeile 10 - hätte ich gestern vielleicht noch etwas deutlicher formulieren können); beide Änderungen ungetestet ...
Grüße
bastla
Mit dem Fehler in Zeile 14 (das Problem war nicht das Aufrunden auf die nächste ganze Zahl, sondern das kaufmännische Runden nach der 4/5-Regel, wodurch dann eben öfter nicht aufgerundet wird) hast Du recht, die Korrektur ist ganz knapp an der Optimallösung vorbei - es sollte nämlich nur .99999 addiert werden, damit nicht für den Fall, dass es genau ein Vielfaches der gewünschten Zeilenanzahl gibt, eine Datei zuviel (würde dann nur die Kopfzeilen enthalten) erzeugt wird ...
Ich korrigiere das oben noch und baue auch die Verwendung eines (als 4. Parameter beim Scriptaufruf) vorgegebenen Zielordners ein (den Hinweis auf die Zeile 9 - ist jetzt Zeile 10 - hätte ich gestern vielleicht noch etwas deutlicher formulieren können); beide Änderungen ungetestet ...
Grüße
bastla
Hallo Bastla!
entschuldige bitte, dass ich mich erst jetzt wieder melde, aber leider hatte ich die letzten Tage beruflich ziemlich viel um die Ohren...
Nach den letzten Anpassungen läuft Dein Script nun absolut tadellos und erleichtert uns die Arbeit wirklich ungemein! Hierfür nochmals ein herzliches Dankeschön!
Da ich ja in Zukunft nicht immer ankommen und darauf hoffen will, dass mir jemand von Grund auf ein Script programmiert, würde ich mich sehr freuen, wenn Du mir zum Abschluss eventuell noch einen Tipp geben kannst, welche Lektüre ich mir für den Einstieg in die VB-Scriptprogrammierung zulegen könnte. Sofern Du mir dahingehend etwas empfehlen kannst, wäre ich Dir besonders dankbar, wenn diese relativ praxisnah gehalten ist.
Grüße
Celimos
entschuldige bitte, dass ich mich erst jetzt wieder melde, aber leider hatte ich die letzten Tage beruflich ziemlich viel um die Ohren...
Nach den letzten Anpassungen läuft Dein Script nun absolut tadellos und erleichtert uns die Arbeit wirklich ungemein! Hierfür nochmals ein herzliches Dankeschön!
Da ich ja in Zukunft nicht immer ankommen und darauf hoffen will, dass mir jemand von Grund auf ein Script programmiert, würde ich mich sehr freuen, wenn Du mir zum Abschluss eventuell noch einen Tipp geben kannst, welche Lektüre ich mir für den Einstieg in die VB-Scriptprogrammierung zulegen könnte. Sofern Du mir dahingehend etwas empfehlen kannst, wäre ich Dir besonders dankbar, wenn diese relativ praxisnah gehalten ist.
Grüße
Celimos
Hallo Bastla,
nach langen suchen im Netz bin ich auf diese Seite und diesen Artikel gestoßen. Ich habe mich bisher noch gar nicht mit VBA beschäftigt, merke aber, dass es einem viel arbeit abnehmen kann.
Ich habe das Script probier und die anfangswerte in die scriptdatei eingefügt. habe meine 60mb große csv auf das script gezogen. Das script macht alles, aber es fehlen die Datenzeiten. Es ist nur die headline vorhanden. kannst Du dir das ggf. erklären.
Besten Dank im Voraus.
Grüße
Thorsten
nach langen suchen im Netz bin ich auf diese Seite und diesen Artikel gestoßen. Ich habe mich bisher noch gar nicht mit VBA beschäftigt, merke aber, dass es einem viel arbeit abnehmen kann.
Ich habe das Script probier und die anfangswerte in die scriptdatei eingefügt. habe meine 60mb große csv auf das script gezogen. Das script macht alles, aber es fehlen die Datenzeiten. Es ist nur die headline vorhanden. kannst Du dir das ggf. erklären.
Besten Dank im Voraus.
Grüße
Thorsten
Hallo csvmaxi und willkommen im Forum!
Und was genau meinst Du mit
Grüße
bastla
P.S.: Die Sprache ist übrigens VBS, nicht VBA ...
Ich habe das Script probier und die anfangswerte in die scriptdatei eingefügt.
Wie sehen die ersten 7 Zeilen des Scripts bei Dir aus?Und was genau meinst Du mit
Das script macht alles, aber es fehlen die Datenzeiten. Es ist nur die headline vorhanden.
Grüße
bastla
P.S.: Die Sprache ist übrigens VBS, nicht VBA ...
Hallo Bastla,
1.anbei die Zeilen:
'SplitTextFile.vbs
sInFile = "D:\1.csv"
lDataLines = "3000"
lHeaderLines = "1"
sOutFolder = "Parts"
sOutFileName = "Part_"
sOutType = ".csv"
Set fso = CreateObject("Scripting.FileSystemObject")
2. In den erstellten Dateien ist nur die Kopfzeilevorhanden, jedoch keine Datensätze.
Thats it is.
Scheinst ja nun im Bett zu liegen. Bin Nachtmensch..
Grüße
Thorsten
1.anbei die Zeilen:
'SplitTextFile.vbs
sInFile = "D:\1.csv"
lDataLines = "3000"
lHeaderLines = "1"
sOutFolder = "Parts"
sOutFileName = "Part_"
sOutType = ".csv"
Set fso = CreateObject("Scripting.FileSystemObject")
2. In den erstellten Dateien ist nur die Kopfzeilevorhanden, jedoch keine Datensätze.
Thats it is.
Scheinst ja nun im Bett zu liegen. Bin Nachtmensch..
Grüße
Thorsten
Hallo csvmaxi!
Zahlenwerte sind in Basic (also auch VBS) ohne Anführungszeichen zu schreiben - daher:
Grüße
bastla
Zahlenwerte sind in Basic (also auch VBS) ohne Anführungszeichen zu schreiben - daher:
'SplitTextFile.vbs
sInFile = "D:\1.csv"
lDataLines = 3000
lHeaderLines = 1
sOutFolder = "Parts"
sOutFileName = "Part_"
sOutType = ".csv"
Set fso = CreateObject("Scripting.FileSystemObject")
bastla