17 berichten aan het bekijken - 1 tot 17 (van in totaal 17)
  • Q:
    Bijdrager
    Sumar

    Applescript: schrijf naar txt bestand vraagje [opgelost]

    Hai,

    Ik heb een tekstbestand (een Gedcom bestand om precies te zijn) dat ik in een keer inlees en dan vervolgens regel voor regel door Applescript laat aanpassen. Dat gaat vlekkeloos in de test (klein bestand).

    Nu heb ik ‘m los gelaten op een bestand van 38.000 regels en dat duurt eindeloos. Om te kijken waar het zit heb ik alle bewerkingen eruit gesloopt en lees alleen het bestand in en schrijf ‘m regel voor regel weg. Dat kost ook ruim een half uur.

    Het wegschrijven doe ik met write Regel to (NewFile as file).

    Heeft iemand een suggestie om dit te versnellen? Een search/replace via Terminal/Textedit oid is geen optie.

    Bijdrager
    Pieterr

    In plaats van een AppleScript een shellscript gebruiken (en dat desnoods vanuit één regel AppleScript aanroepen)?

    do shell script "bla die bla"

    Je zult het AppleScript dan wel moeten herschrijven naar een shell script.

    Wat moet er precies gebeuren met die regels?

    Bijdrager
    dj bazzie wazzie

    waarschijnlijk gebruik je een standaard repeat functie. Je kunt een repeat functie versnellen door references te gebruiken in plaats van steeds het object aan te roepen. Een snelste repeat is een script object te gebruiken.

    <br />
    script speedup<br />
    	property speedList : {}<br />
    end script<br />
    set speedup's speedList to deLijstMetItems<br />
    repeat with x from 1 to count speedup's speedList<br />
    --nu is de repeat zelf velen malen sneller en waarschijnlijk klaar in binnen een seconde<br />
    --om een item aan te speken gebruik je item x of speedup's speedList<br />
    end<br />
     
    Bijdrager
    Sumar

    @Pieterr:
    Dit type regels moeten aangepast worden:

    2 FILE ~/Documents/Genealogy Data/foto 01.tif naar 2 FILE [een ander pad]/foto 01.tif of
    2 FILE /Volumes/Data/Genealogy Data/foto 01.tif naar 2 FILE [een ander pad]/foto 01.tif

    Het andere pad wordt door het Applescript bepaald (subfolder van de folder waar het invoerbestand in staat). Daarna worden de orginele bestanden gekopieerd naar die folder. Ik weet dus niet van te voren wat er aangepast moet worden naar waar.

    @dj bazzie wazzie:
    Klopt: ik gebruik repeat. Van speedlist nog nooit gehoord, dank voor de tip. Ik ga daar eens mee stoeien.

    Bijdrager
    Sumar

    @dj bazzie wazzie:

    Dank ! Van dik een half uur terug naar 20 sec.

    Bijdrager
    dj bazzie wazzie

    Graag gedaan!

    Toch nog een enkele vraag. Die 20 seconden is dat de tijdsduur van het gehele proces of alleen inlezen en wegschrijven? Hier een script dat een bestand met 38.000 regels met ‘Hello’ wegschrijft naar een nieuwe bestand en daarbij achter elke regel ” world!” plaatst zodat het nieuwe bestand 38.000 regels ‘Hello world!” bevat en dit uitgevoerd in 2 seconden. Ik zou bijna zeggen dat in puur applescript dit het snelste is dat je kan krijgen zonder gebruik te maken van speciale additions of gebruik te maken van command line utilities.

    <br />
    set sourceFile to "/Users/<gebruiker>/Desktop/helloWorld(in).txt" as string<br />
    set targetFile to "/Users/<gebruiker>/Desktop/helloWorld(out).txt" as string<br />
    set lineTerminator to string id 10<br />
    try<br />
    	set fd to open for access POSIX file sourceFile<br />
    	set speedup's sourceLines to read fd using delimiter lineTerminator<br />
    	close access fd<br />
    	set errmsg to ""<br />
    on error errmsg<br />
    	close access POSIX file sourceFile<br />
    	display dialog errmsg<br />
    	return<br />
    end try<br />
    repeat with theValue in speedup's sourceLines<br />
    	set end of speedup's targetLines to (contents of theValue & " World!" as string)<br />
    end repeat<br />
    set AppleScript's text item delimiters to lineTerminator<br />
    set contentsForFile to speedup's targetLines as string<br />
    set AppleScript's text item delimiters to ""<br />
    try<br />
    	set fd to open for access POSIX file targetFile with write permission<br />
    	set eof of fd to 0<br />
    	write contentsForFile to fd<br />
    	close access fd<br />
    	set errmsg to ""<br />
    on error errmsg<br />
    	close access POSIX file targetFile<br />
    	display dialog errmsg<br />
    	return<br />
    end try<br />
    script speedup<br />
    	property sourceLines : {}<br />
    	property targetLines : {}<br />
    end script<br />
     
    Bijdrager
    Sumar

    Die 20 sec is het hele proces, dus incl alle extra handelingen als bestanden kopieeren.

    Ik lees het invoerbestand overigens in via set InhoudBestand to (do shell script “cat ‘” & DroppedGedcomFile & “‘”)

    Ik zal jouw variant eens verder bekijken of die sneller is.

    Bijdrager
    Verwijder

    tip: TextWrangler is scriptable. Je kan met AppleScript TextWrangler het tekstdocument laten openen en de aan te passen regels opzoeken en wijzigen. Je hoeft dan niet alle regels te controleren. Afhankelijk van hoe complex het bepalen van het nieuwe pad is kan je misschien met een regular expression de paden in één keer vervangen.

    Bijdrager
    Sumar

    Het in een keer vervangen is onmogelijk: hetgeen vervangen moet worden is nogal variabel is (kan in theorie maar een keer voorkomen in het bestand).

    De bedoeling is overigens dat het ooit een applicatie wordt (met een complete GUI) en dan wil je niet afhankelijk zijn van een extern programma (maar dat kon je niet weten).

    Bijdrager
    dj bazzie wazzie

    @willemien: klopt helemaal. Awk is bijvoorbeeld een goed programma waarmee je met awk scripts super snel iets kan omzetten in een enkel do shell script commando. Maar Sumar gaf aan dat terminal (ging ervan uit do shell script dan ook) textEdit of iets dergelijks geen optie was.

    @sumar: Het is niet verstandig om zelf een quoted form te gebruiken. Er kunnen bestandsnamen voorkomen die cat nu niet kan afhandelen. Mocht je cat willen blijven gebruiken om een bestand in te lezen gebruik dan set InhoudBestand to do shell script “cat ” & quoted form of DroppedGedcomFile. Nu weet je zeker dat je bestand op de juiste manier escaped wordt. Een ander hele klein puntje is dat je variabele namen beter met een kleine letter kan laten beginnen. Mocht je een keer willen overstappen naar applescriptObjC weet je zeker dat je applescript variabele naam niet botst met systeem variabelen in het cocoa framework.

    Bijdrager
    Verwijder

    Hoeveel foto’s zijn het ongeveer? Zit de tijd nu vooral in het kopiëren van de foto’s?

    Als het een Cocoa-applicatie wordt dan wordt het veeeel sneller als je AppleScript omzet naar Objective-C.

    Bijdrager
    Sumar

    @dj bazzie wazzie:
    Dank. Die had ik even over het hoofd gezien. Zal de variabelen aanpassen.

    @Willemien:
    Op het moment zijn het er 41, er zitten een paar grote bij (80mb) en ze komen van verschillende bronnen (HD, USB en een van het netwerk). Dat ze overal staan is meer om te testen hoe het een en ander werkt (bv wat er gebeurd als een USB stick er niet in zit).

    Ik ga nog even door met Applescript totdat ik tevreden met het programma, daarna zien we wel hoe het om te zetten is naar een ‘echte’ app die door iedereen zonder problemen te gebruiken is (heb daar totaal geen ervaring mee).

    Bijdrager
    dj bazzie wazzie
    Willemien op 03 maart 2011

    Als het een Cocoa-applicatie wordt dan wordt het veeeel sneller als je AppleScript omzet naar Objective-C.

    Dat is sinds 10.6 niet meer zo. Applescript applicaties met GUI worden niet meer afgehandeld zoals in voorgaande systemen. Je moet wel de applicaties volledig herschrijven trouwens. Oude Applescript-Studio applicaties blijven op in 10.6 gewoon op de ouder manier werken.

    Bijdrager
    Verwijder

    Ik had laatst een stukje AppleScript wat niet vooruit te branden was, ik heb het omgezet naar Objective-C en het is vliegensvlug. Het omzetten was erg eenvoudig, ik kon regel voor regel de syntax veranderen en hoefde niks om te gooien. Ik heb wel alles wat het script tegen Scripting Additions en de Finder stond te praten omgezet naar Cocoa en Core Foundation, dat is wat meer werk.
    Ik heb geen ervaring met AppleScriptObjC, wel met het omgekeerde: Scripting Bridge, dat zou twee keer zo snel zijn als AppleScript (in 10.5).
    Draait AppleScript sneller in een applicatie met GUI dan in AppleScript Editor?
    Nu wil ik het weten ook, ik zal even wat experimenteren met bovenstaand script.

    Bijdrager
    Verwijder

    De uitslagen:

    Bovenstaand AppleScript met als input een Gedcom-bestand met ruim 50.000 regels.

    AppleScript in AppleScript Editor: eerste keer 5, volgende keren 3 seconden
    AppleScript in een Cocoa-AppleScript Application: eerste keer 6, volgende keren 3 seconden
    Objective-C in een Cocoa Application: gemiddeld 0,16 seconden

    In het script zit een bugje: targetLines wordt niet leeggemaakt, elke keer als het script wordt uitgevoerd komen de regels erbij, duurt het langer en wordt de output file groter.

    Bijdrager
    Verwijder

    Ik was geïntrigeerd door de truc met de properties van een ander script object waardoor het veel sneller zou zijn, ik kende hem nog niet. Dat het sneller is is wel duidelijk, maar het kan ook zonder extra script object:

    <br />
    repeat with x in a reference to deLijstMetItems<br />
    -- doe iets met x<br />
    end<br />
     
    Bijdrager
    dj bazzie wazzie

    Klopt helemaal. A reference to werkt ook alleen script object is een persoonlijke keuze voor mij omdat ik er meerdere properties in kan verwerken.

    ApplescriptObjC is bij mij ook 0.2 seconden maar moet ik er wel bij verklappen dat ik geen applescript object heb gebruikt als string of list maar NSArrays en NSString objecten om de snelheid er bij applescript in te houden. Dus de complete file handling heb ik aan cocoa overgelaten en niet geprobeerd met applescript zelf te doen.

    Dat targetLines niet wordt geleegd is een goed punt maar geen probleem in een applicatie alleen als een op zichzelf staand script wordt opgeslagen als programma wordt het inderdaad een probleem.

17 berichten aan het bekijken - 1 tot 17 (van in totaal 17)

Je moet ingelogd zijn om een reactie op dit onderwerp te kunnen geven.