Hallo Goar,
also ... die Meldungen betreffend gesättigtem Speicher habe ich zuverlässig reproduzieren
können. Und auch die 31-MB-Grösse des Scripts. Letzteres Problem tritt mit dem untenstehenden
Script nicht mehr auf, weil die beiden Befehle 'set allText to ""' und 'set curParas to ""'
die Variablen leeren.
Damit beim Lesen grosser Dateien kein Überlauf entsteht, wird allgemein geraten, den Text
häppchenweise (= chunks) einzulesen. Die Datei zum Lesen öffen, nicht schliessen, sondern
laufend mit 'read for' die gewünschte Anzahl Bytes einlesen. Wenn man aber Suchen- und
Ersetzenbefehle auf den aktuellen Happen anwendet, dann ist die Möglichkeit gross, dass sich
ein Teil des Suchstrings am Ende befindet und der Rest im nächsten Chunk. So geht es also nicht.
Deshalb den ganzen Text (= 387'613 Absätze) auf einmal in eine Variable lesen. Dann mit einer
Repeatschleife eine gewisse Anzahl Absätze behandeln und das Ergebnis in die Textdatei schreiben.
Mit einer Chunk-Grösse von 10'000 Absätzen kommt aber wieder die gefürchtete Meldung. Den Wert
auf 1000 reduzieren: Jetzt klappt es!
Nach genau 6 Minuten kommt die Meldung "Fertig." Es werden also alle 0.928 Sekunden
1000 behandelte Absätze in die Datei geschrieben.
Ein weiterer Vorteil: Wenn Satimage kleinere Mengen aufs Mal bearbeiten muss, wird der Ablauf
deutlich schneller. Feststellbar mit der 12-MB-Datei, welche auch ohne den Chunks-Trick keine
Fehlermeldung verursacht.
Einige Bemerkungen: Weil die Dateien nur einmal geöffnet werden, ist es nicht notwendig, sie
vor dem Lesen zu öffnen und dann wieder zu schliessen. Der 'read'-Befehl macht dies automatisch.
Und weil es ja ein Textfile ist, muss nicht 'as text' präzisiert werden.
Der Test, welcher den Tabellenkopf zuordnet, muss vor der Absatz-Repeatschleife gemacht werden,
sonst wird diese Zeile bei jedem Umgang eingefügt.
Damit der aktuelle Text-Chunk bei jedem Schreiben angefügt wird, muss die Zeile 'set eof to 0'
entfernt und die 'write'-Zeile mit 'starting at eof' ergänzt werden. Das bedingt natürlich, dass
nach Ablauf des Scripts die Datei verschoben wird. Falls sie überschrieben werden soll, dann
könnte man einen zweiten Handler einrichten, welcher aufgerufen wird, wenn die Kopfzeile in die
Datei geschrieben werden soll.
---
set folderPath to (path to "cusr" as Unicode text) & "Documents:1SatzG5:Huxaria:"
set importFolder to folderPath & "1 Eingang:"
set impDataFiles to {"400 Original.dat", "400.031", "400.033", "400.023"}
set DataFiles4DB to {"Opti4DB.txt", "Conti4DB.txt", "Gates4DB.txt", "Ruville4DB.txt"}
set Feldnamen to {"OptiArt DSR GenArtNr LKZ LfdNr SortNr Rest", "FremdArt DSR GenArtNr LKZ LfdNr SortNr Rest"}
set aChunk to 1000
set protokoll to ((current date) as string) & return & "Eingangsdaten" & return
repeat with i from 3 to count of impDataFiles
set tmpFilePath to importFolder & item i of impDataFiles
set defFilePath to importFolder & item i of DataFiles4DB as string
set allText to read file tmpFilePath
set cntPara to (count of paragraphs of allText) - 1
set protokoll to protokoll & item i of impDataFiles & " enthält " & cntPara & " Verknüpfungen." & return
if i = 1 then
set curHead to item i of Feldnamen & return
else
set curHead to item 2 of Feldnamen & return
end if
writeFile(defFilePath, curHead)
set AppleScript's text item delimiters to {return}
repeat with p from 1 to cntPara by aChunk
if cntPara > aChunk then
if p < cntPara - (cntPara mod aChunk) then
set curParas to ((paragraphs p thru (p - 1 + aChunk) of allText) as string) & return
else
set curParas to ((paragraphs p thru cntPara of allText) as string) & return
end if
else
set curParas to ((paragraphs p thru cntPara of allText) as string) & return
end if
if curParas is not "" then
set curParas to (change (ASCII character 10) into "" in curParas)
set curParas to (change ¬
"(^.{22})(.{12})(.{5})(.{3})(.{9})(.{5})(.)" into ¬
"\\1§\\t\\2\\t\\3\\t\\4\\t$\\5\\t$\\6\\t\\7" in curParas with regexp)
set curParas to (change "[ ]*§" into "" in curParas with regexp)
set curParas to (change "[$][0]*" into "" in curParas with regexp)
set curParas to (change "\" " into "? " in curParas)
writeFile(defFilePath, curParas)
end if
end repeat
set AppleScript's text item delimiters to {""}
set allText to ""
set curParas to ""
end repeat
set defFilePath to folderPath & "Testprotokoll"
set protokoll to protokoll & return & ((current date) as string) & return
set allText to protokoll
writeFile(defFilePath, allText)
on writeFile(defFilePath, allText)
try
open for access file defFilePath with write permission
write allText to file defFilePath starting at eof
close access file defFilePath
on error
try
close access file defFilePath
end try
end try
end writeFile
beep
tell application "Finder" to display dialog "Fertig." buttons {"OK"} default button 1
protokoll
---
Okay ... ich nehme an, dass es mit Perl einfacher und schneller wäre. Doch das wird die nächste Etappe sein.
Gruss, Hans
als Antwort auf: [#419503]