Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 17.01.2006 - 21:50 Titel: String in Dateien suchen (mit Platzhalter) und auslesen |
|
|
Hallöle zusammen
hab mal wieder eine aufgabe, bei der ich nicht so recht weiß, wie ich drangehen soll:
ich möchte in dateien nach einem textstring suchen. das größte problem dabei ist, das ich dabei quasi noch platzhalter benötige.
konkret heisst das, dass ich eigentlich den textstring zwischen einem startstring und einem endstring erhalten möchte. es kommt erschwerend hinzu, dass startstring und endstring mehrmals im file vorkommen, ich aber nur den string zwischen den beiden erhalten möchte, wenn diese aufeinandertreffen. beispiel:
Code: | "(BlaBla" kommt häufiger im file vor
")ende" kommt auch häufiger vor
ich will aber nur den wert, der zwischen den beiden steht:
"(BlaBla####)ende #### möchte ich in eine variable übergeben
#### kann dabei 1 bis maximal 4 zeichen lang sein |
Habt ihr eine Idee? _________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 20.01.2006 - 19:23 Titel: Ich hab's, aber leider etwas "suboptimal" |
|
|
Hallo zusammen!
Um's mit Ex-Kanzlers Worten zu sagen: Ich habe eine "suboptimale" Lösung für mein Problem gefunden. Zunächst einmal habe ich doch einen eindeutigen String-Teil gefunden, nach dem ich im Text suchen kann, so dass sich die Sache mit dem Platzhalter erledigt hätte (und somit eigentlich ein etwas anderes Thema).
Ich hab mir den Thread "Read File" von pal05 zu Gemüte geführt, und folgendes Script geschrieben, das auch funktioniert, aber leider nicht sehr performant ist:
Zitat: | set datei to "MacOS9:testdatei.txt"
set RefNum to open for access alias datei
set erg to ""
try --zeilenweise dateiprüfung durch "before return"
repeat while (erg = "") is true
read RefNum before return
set zeile to result
if (zeile contains "cm Abstand ") then set erg to text from ((offset of "cm " in zeile) + 3) to ((offset of "en" in zeile) + 2) in zeile
end repeat
close access RefNum
display dialog erg
on error errMsg
display dialog "Fertig" & return & errMsg
close access RefNum
end try
|
Das funktioniert prima, aber die Dateien, die durchsucht werden sollen (beim Beispielscript ja zeilenweise), sind z.T. mehrere MB gross, und da der Test mit einer 380KB-Datei bereits ein weilchen dauert, ist das für mich leider so nicht brauchbar.
Gibt es vielleicht die Möglichkeit, von vornherein nur einen Teil der gelesen Datei in eine Variable zu speichern, damit ich diese dann konkret mit der schleife (oder auch ohne) durchsuchen kann. Ich weiss z.B., dass der gewünschte string ziemlich am Ende der Dateien vorliegt.
Gibt es also bspw. eine Möglichkeit, die letzten 1000 Zeichen aus der Datei in einem Rutsch einzulesen, damit ich diese dann innerhalb des Scripts durchsuchen kann? (Die ganze Datei kann ich nicht im Rutsch einlesen, da es dann zu speicherproblemen kommt).
Könnt ihr mir da mal auf die Sprünge helfen? _________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
Snow Administrator


Anmeldedatum: 21.11.2000 Beiträge: 1946 Wohnort: Deiningen
|
Verfasst am: 20.01.2006 - 23:00 Titel: |
|
|
Nur die letzten 1000 Zeichen einlesen geht so:
set Pfad to (path to desktop as string) & "regex.txt"
set theRef to open for access file Pfad
set theText to read theRef from -1000
close access theRef
get theText
Für die Suche im Text bieten sich Regular Expressions an. Unter OS 9 kannst du dafür die Satimage OSAX verwenden. Unter OS X gibt's die natürlich auch, dort kannst du aber auch per shell script arbeiten z.B. mit 'grep', was den Vorteil hat, dass du nicht extra in eine Variable einlesen musst, sondern direkt den Pfad zur Datei an den shell-Befehl weitergibst.
Hier nun ein Beispiel mit der Satimage OSAX:
set myText to "Laber laber(BlaBla1a2b3c4d5e678)ende und weiterer Text"
set Suchmuster to "\\(BlaBla(.*)\\)ende"
try
set Ergebnis to find text Suchmuster in myText with regexp
set resultText to matchResult of Ergebnis
display dialog "Gefunden: \"" & resultText & "\""
-- Ergebnis:
-- "Gefunden: "(BlaBla1a2b3c4d5e678)ende"
set dazwischen to (characters 8 thru -6 of resultText) as string
display dialog "Zwischen den Suchworten steht: \"" & dazwischen & "\""
-- Ergebnis:
-- Zwischen den Suchworten steht: "1a2b3c4d5e678"
on error number errNr
if errNr = 1 then
display dialog "Leider nichts gefunden!"
end if
end try _________________ Peter
-
Fischer-Bayern.de|Shadetreemicro.com |
|
Nach oben |
|
 |
Snow Administrator


Anmeldedatum: 21.11.2000 Beiträge: 1946 Wohnort: Deiningen
|
Verfasst am: 20.01.2006 - 23:10 Titel: |
|
|
Wenn du eine Datei zeilenweise einlesen möchtest, brauchst du folgende Zeile innerhalb einer Schleife:
set myText to read theRef before return
Nach dem Einlesen muss der Text gleich verarbeitet werden, damit du die weiteren Zeilen einlesen kannst.
Der 'read'-Befehl liest an der Stelle weiter, wo er zuvor aufgehört hatte.
Erst mit close access ist der gesamte Lesevorgang beendet und beginnt beim nächsten Mal wieder am Anfang der Datei.
Vergleiche hierzu auch: http://www.fischer-bayern.de/phpBB2/viewtopic.php?t=680 _________________ Peter
-
Fischer-Bayern.de|Shadetreemicro.com |
|
Nach oben |
|
 |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 20.01.2006 - 23:20 Titel: |
|
|
hallo snow
ich hab's jetzt doch mit dem einlesen des kompletten textes getestet.
habe jetzt auch den entsprechenden part extrahieren können in angemessener zeit.
mein problem jetzt ist, das das mit so 500KB-dateien richtig gut und flott vonstatten geht, bei ein 10MB-datei bekomme ich aber einen "out of memory".
ich bräuchte jetzt also ein lösung, den text häppchen-weise einzulesen, so vielleicht 1MB-weise (zeilenweise war ja zu langsam), zu suchen, und wenn nicht vorhanden, nächstes häppchen. mit einer repeat-schleife sollte ich mich ja wohl durchschlängeln können.
ich probier mal weiter.
vielen dank, da war natürlich wieder einiges verwertbares dabei. _________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
Snow Administrator


Anmeldedatum: 21.11.2000 Beiträge: 1946 Wohnort: Deiningen
|
Verfasst am: 21.01.2006 - 01:31 Titel: |
|
|
Der read-Befehl bietet ja noch so einige Optionen an z.B.:
for double integer] : the number of bytes to read from current position; if omitted, read until the end of the file…
Kleines Beispiel:
global zaehler
set zaehler to 0
set theFile to (path to desktop as string) & "regex.txt"
set theRef to open for access file theFile
repeat
try
set myText to read theRef for 1024
testing(myText)
on error -- wenn Dateiende (eof) erreicht wird
exit repeat
end try
end repeat
close access theRef
on testing(theText)
set zaehler to zaehler + 1
if theText contains "(BlaBla" then
display dialog "Treffer im Textteil Nr. " & zaehler with icon note
end if
end testing
Den Wert, der angibt, wie viel Text (in Bytes) eingelesen werden soll, kannst du natürlich an deine Bedürfnisse anpassen.
Praktisch ist es in diesem Zusammenhang auch, wenn du den Wert in Klammern packst und einfach multiplizierst - so musst du keine rießigen Zahlen unterbringen.
set myText to read theRef for (1024 + 1024) _________________ Peter
-
Fischer-Bayern.de|Shadetreemicro.com |
|
Nach oben |
|
 |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 21.01.2006 - 18:55 Titel: |
|
|
hallo snow
habs ein wenig anders gelöst, da ich ja nach einem start- und end-string suche, um teil dazwischen auszulesen, habe ich die häppchen per repeat etwas überlappen lassen (schnittmenge von 2000 zeichen), da es sonst ja passieren könnte, das ich in dem jeweiligen "häppchen" nur den start- oder den end-string enthalten habe. da diese aber nie weiter als 2000 byte auseinanderliegen können, hab ich's damit ausgeschlossen.
hast du da noch eine bessere lösung (ich denke schon!)? es funzt aber auch so.
und da der gesuchte string sich immer im hinteren bereich der datei befindet, habe ich aus performance-gründen die repeats mit *-1 umgedreht, damit's von hinten anfängt mit der analyse.
Code: | set diedatei to file "HD1:testdatei.txt"
try
set RefNum to open for access alias diedatei
set z to 1
set x to 0
repeat until x = 1
set teil to text in (read RefNum from (z + 22000) * -1 to (z * -1))
if (teil contains "Hier starten") and (teil contains "Hier stoppen") then set x to 1
set z to z + 20000
end repeat
close access RefNum
on error errMsg
close access RefNum
end try
set temp to text from ((offset of "Hier starten" in teil) + 12) to (offset of "Hier stoppen" in teil) in teil
set AppleScript's text item delimiters to " "
set IchHabs to (text items of temp)
set AppleScript's text item delimiters to {""} -- original delimiter
tell application "Finder"
set name of file diedatei to IchHabs
end tell |
_________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 21.01.2006 - 19:01 Titel: |
|
|
muss ich denn grundsätzlich teile der datei ins script einlesen per "read" und in eine variable speichern, um einen bestimmten auszug der datei zu erhalten, oder gibt es gar eine möglichkeit, ganz gezielt nur einen bestimmten teil per read ins script einzulesen (ausser der möglichkeit die zeichen per zahl anzugeben, die gelesen werden soll)?
ist also eine analyse ausserhalb von script-variablen direkt in der datei möglich?
da du sonst auch alles weißt, snow,
wirst du mich sicher nicht enttäuschen ;o) _________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
Skeeve •---->


Anmeldedatum: 20.04.2006 Beiträge: 1067
|
Verfasst am: 25.04.2006 - 00:37 Titel: Re: String in Dateien suchen (mit Platzhalter) und auslesen |
|
|
iScript hat Folgendes geschrieben: | Code: | "(BlaBla" kommt häufiger im file vor
")ende" kommt auch häufiger vor
ich will aber nur den wert, der zwischen den beiden steht:
"(BlaBla####)ende #### möchte ich in eine variable übergeben
#### kann dabei 1 bis maximal 4 zeichen lang sein |
Habt ihr eine Idee? |
Muß es AppleScript sein? Probier mal das hier (Eingebunden in AppleScript):
Code: |
set ergebnis to do shell script "perl -ne 'print qq<$1\n> if /\(BlaBla(.{1,4})\)ende/;' " & quoted form of POSIX path of myFile;
|
ACHTUNG: Ungetestet! |
|
Nach oben |
|
 |
iScript •---->


Anmeldedatum: 29.03.2001 Beiträge: 1116
|
Verfasst am: 25.04.2006 - 00:51 Titel: |
|
|
das sollte ne sache für's 9er system sein, und da gibt's ja noch keine shellscript's. läuft aber jetzt so.
ich muss das ganze irgendwann aber mal auf X rübernehmen, und dann komme ich gern drauf zurück. _________________ - anholn deit kriegen - |
|
Nach oben |
|
 |
Skeeve •---->


Anmeldedatum: 20.04.2006 Beiträge: 1067
|
Verfasst am: 25.04.2006 - 11:04 Titel: |
|
|
iScript hat Folgendes geschrieben: | das sollte ne sache für's 9er system sein, |
Sorry! War mir nicht aufgefallen, weil ich über die Suche hier gelandet bin.
Vielleicht reicht für Deinen Anwendungsfall aber auch reines perl, wenn Du kein GUI brauchst. Für solche Geschichten, nämlich Texte zu filtern, ist perl prädestiniert.
Aber genug Off Topic  |
|
Nach oben |
|
 |
|