Textdatei per Batch in mehrere aufteilen
Hallo zusammen,
ich habe folgendes Problem.
Ich habe eine Textdatei, die sehr viele Zeilen enthält (>10000 Zeilen).
Eine vorhandene Batch geht her und liest nacheinander eine Zeile aus, macht damit etwas, und schreibt das Ergebnis in eine Ausgabedatei.
So geht die Batch von Zeile zu Zeile, was natürlich entsprechend lange dauert, bis alle Zeilen durch sind.
Nun habe ich mir überlegt, dass man das ganze Parallel laufen lassen könnte.
Sprich ich teile die Quell-Textdatei in mehrere Teile, verteile diese auf mehrere Ordner, und starte in jedem Ordner die jeweilige Batch-Datei, die die Verarbeitung pro Zeile in der jeweiligen Teil-Quell-Datei übernimmt.
Am Ende, wenn alle Batch-Dateien durchgelaufen sind, füge ich die verschiedenen Ausgabe-Dateien der verschiedenen Ordner zusammen.
Das Zusammenfügen mache ich am einfachsten mit dem for-Befehl. Ich lasse in jedem Ordner jeweils die Ausgabedatei zeilenweise lesen und schreibe das ganze dann in eine große Ausgabedatei.
Mein Problem:
Wie teile ich die große Quelldatei in möglichst gleichmäßige Teile auf. Sprich ich habe 10 Ordner, in die jeweils eine Teil-Quelldatei mit ungefähr gleich viel Zeilen soll.
Wie könnte ich sowas am elegantesten machen? Wichtig wäre, dass halt immer genau 10 Teildateien rauskommen.
Sprich wenn nur 10 Zeilen in der großen Quelldatei stehen, dann sollen halt 10 Dateien mit jeweils einer Zeile davon rauskommen, umgekehrt bei 10000 Zeilen eben 1000 Zeilen pro Datei.
Viele Grüße
Martin
ich habe folgendes Problem.
Ich habe eine Textdatei, die sehr viele Zeilen enthält (>10000 Zeilen).
Eine vorhandene Batch geht her und liest nacheinander eine Zeile aus, macht damit etwas, und schreibt das Ergebnis in eine Ausgabedatei.
So geht die Batch von Zeile zu Zeile, was natürlich entsprechend lange dauert, bis alle Zeilen durch sind.
Nun habe ich mir überlegt, dass man das ganze Parallel laufen lassen könnte.
Sprich ich teile die Quell-Textdatei in mehrere Teile, verteile diese auf mehrere Ordner, und starte in jedem Ordner die jeweilige Batch-Datei, die die Verarbeitung pro Zeile in der jeweiligen Teil-Quell-Datei übernimmt.
Am Ende, wenn alle Batch-Dateien durchgelaufen sind, füge ich die verschiedenen Ausgabe-Dateien der verschiedenen Ordner zusammen.
Das Zusammenfügen mache ich am einfachsten mit dem for-Befehl. Ich lasse in jedem Ordner jeweils die Ausgabedatei zeilenweise lesen und schreibe das ganze dann in eine große Ausgabedatei.
Mein Problem:
Wie teile ich die große Quelldatei in möglichst gleichmäßige Teile auf. Sprich ich habe 10 Ordner, in die jeweils eine Teil-Quelldatei mit ungefähr gleich viel Zeilen soll.
Wie könnte ich sowas am elegantesten machen? Wichtig wäre, dass halt immer genau 10 Teildateien rauskommen.
Sprich wenn nur 10 Zeilen in der großen Quelldatei stehen, dann sollen halt 10 Dateien mit jeweils einer Zeile davon rauskommen, umgekehrt bei 10000 Zeilen eben 1000 Zeilen pro Datei.
Viele Grüße
Martin
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 96618
Url: https://administrator.de/contentid/96618
Ausgedruckt am: 22.11.2024 um 10:11 Uhr
7 Kommentare
Neuester Kommentar
Servus,
ein möglicher Ansatz wäre:
so bekommst du schonmal die komplette Anzahl der Zeilen heraus, ohne vorher "wirklich" die ganze Datei mit einer For Schleife durchzuackern.
...aber wie dann weiter?
Eher weniger, mach lieber ein copy text1.txt + text2.txt komplett_text.txt, dein Ziel ist es doch, "schneller" zu werden.
Gruß
ein möglicher Ansatz wäre:
rem arbeitskopie
copy meinetextdatei.txt meintextdatei.ini
@echo endeglaende >> meintextdatei.ini
find /n "endeglaende" meintextdatei.ini
...aber wie dann weiter?
Das Zusammenfügen mache ich am einfachsten mit dem for-Befehl.
Ich lasse in jedem Ordner jeweils die Ausgabedatei zeilenweise lesen und schreibe das ganze dann in eine große Ausgabedatei.
Ich lasse in jedem Ordner jeweils die Ausgabedatei zeilenweise lesen und schreibe das ganze dann in eine große Ausgabedatei.
Eher weniger, mach lieber ein copy text1.txt + text2.txt komplett_text.txt, dein Ziel ist es doch, "schneller" zu werden.
Gruß
Hallo blacksun!
Wie schon von TimoBeil richtig festgestellt, muss zum Aufteilen jede Zeile gelesen und geschrieben werden, dazu noch die Abfrage, ob die Grenze für einen Teil bereits erreicht ist - wenn das alles in Batch passiert, wird der ev durch die folgende Parallelverarbeitung zu erzielende Vorteil dadurch vermutlich schon zunichte gemacht.
Als Alternative könnte daher (mal wieder ) VBS herhalten:
Für 66000 Zeilen zu je etwa 65 Zeichen läuft das Script bei mir etwa 40 Sekunden ...
Grüße
bastla
Wie schon von TimoBeil richtig festgestellt, muss zum Aufteilen jede Zeile gelesen und geschrieben werden, dazu noch die Abfrage, ob die Grenze für einen Teil bereits erreicht ist - wenn das alles in Batch passiert, wird der ev durch die folgende Parallelverarbeitung zu erzielende Vorteil dadurch vermutlich schon zunichte gemacht.
Als Alternative könnte daher (mal wieder ) VBS herhalten:
Quelle = "D:\Datei.txt"
Ziel = "D:\Teil"
Set fso = CreateObject("Scripting.FileSystemObject")
T = Split(fso.OpenTextFile(Quelle).ReadAll, vbCrLF)
U = UBound(T)
S = Int(U / 10)
For i = 1 To 9
W = ""
For j = (i - 1) * S To i * S - 1
W = W & T(j) & vbCrLF
Next
fso.CreateTextFile(Ziel & i & ".tmp", True).Write W
Next
W = ""
For j = 9 * S To U
W = W & T(j) & vbCrLF
Next
fso.CreateTextFile(Ziel & "10.txt", True).Write W
Grüße
bastla
Hmmja, bastla,
das ist natürlich eine Lösung für die Aufgabenstellung (und sogar eine kurze und knackige Lösung!), aber....
Hey, lass uns mal zwei Schritte zurücktreten und dann noch mal draufgucken...
Ööööhmmm.....
Also nee....
Jetzt würde ich bewerten und abwägen...
So wie jetzt möchte ich es als "Lösung" eigentlich nicht im Forum stehen haben.
Grüße
Biber
das ist natürlich eine Lösung für die Aufgabenstellung (und sogar eine kurze und knackige Lösung!), aber....
Hey, lass uns mal zwei Schritte zurücktreten und dann noch mal draufgucken...
- Jetzt nudeln wir eine Zig-Zehntausende-Zeilen-Datei in sportlichen 40 sec durch und portionieren die in 10 handlichere Häppchen,....
- damit danach 10 eher drömelige Bätche es zeitlich auf die Reihe bekommen, vor dem Morgengrauen eines dieser Häppchen abzufrühstücken..
- und sich dann wie die 7 (+3) Zwerge darum balgen, die Ergebnisse wieder in eine Final-Outputdatei zu schreiben....
Ööööhmmm.....
Also nee....
Jetzt würde ich bewerten und abwägen...
- wenn das Weiterlaufen der bisherigen Lösung das Ziel ist: Dann soll doch der heutige Batch morgens um 02h per Taskplaner gestartet werden und meinetwegen 2 Stunden rumrödeln
- wenn Performance-Tuning das Ziel ist, dass lass uns die ganze Aufgabe per VBS (oder besserem) abfackeln. Besser im Sinne von: Weniger Interpreter, mehr Kompilertes.
So wie jetzt möchte ich es als "Lösung" eigentlich nicht im Forum stehen haben.
Grüße
Biber
@Biber
Dann gilt also für obiges Script: "Habe Lösung - suche Problem."
Allerdings muss ich Dir (kostet mich allerdings keine Überwindung ) natürlich Recht geben ...
Grüße
bastla
Dann gilt also für obiges Script: "Habe Lösung - suche Problem."
Allerdings muss ich Dir (kostet mich allerdings keine Überwindung ) natürlich Recht geben ...
Grüße
bastla
Hallo bastla,
das vbs-Prg ist echt super.
Die Orginaldatei wird in gleich große Teile gesplittet.
Wie ändert man das vbs, wenn man fixe Mengen z. B. 20.000 Datensätze pro Teildatei
splitten will und der Rest kommt in die letzte Teildatei?
Gruß, netkid
p.s. Habe doch noch 'ne Lösung gefunden: VBS splitting-large-files-using
Code:
das vbs-Prg ist echt super.
Die Orginaldatei wird in gleich große Teile gesplittet.
Wie ändert man das vbs, wenn man fixe Mengen z. B. 20.000 Datensätze pro Teildatei
splitten will und der Rest kommt in die letzte Teildatei?
Gruß, netkid
p.s. Habe doch noch 'ne Lösung gefunden: VBS splitting-large-files-using
Code:
''This simple VBScript spilts large text files into multiple files
Dim Counter
Const InputFile = "C:\input.txt"
Const OutputFile = "C:\output"
Const RecordSize = 200000
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile (InputFile, ForReading)
Counter = 0
FileCounter = 0
Set objOutTextFile = Nothing
Do Until objTextFile.AtEndOfStream
if Counter = 0 Or Counter = RecordSize Then
Counter = 0
FileCounter = FileCounter + 1
if Not objOutTextFile is Nothing then objOutTextFile.Close
Set objOutTextFile = objFSO.OpenTextFile( OutputFile & "_" & FileCounter & ".csv", ForWriting, True)
end if
strNextLine = objTextFile.Readline
objOutTextFile.WriteLine(strNextLine)
Counter = Counter + 1
Loop
objTextFile.Close
objOutTextFile.Close
Msgbox "Split process complete"