2 votos

¿Cómo introducir un objeto de lista que se guarda en un archivo .txt a un AppleScript?

Tengo un AppleScript .scpt archivo, provocado por una combinación de teclas en FastScripts.la aplicación, que funciona como un diccionario de sinónimos. El script busca la palabra seleccionada en una pre-lista formateada, y, si la palabra se encuentra en esta lista, se muestra el sinónimos de esta palabra para el usuario1.

Esta lista está contenida en un texto sin formato (.txt) archivo. La lista ya está formateado en el AppleScript list formato. Me gustaría que mi .scpt archivo para ser capaz de aceptar este texto como una verdadera lista2.

Es importante tener en cuenta que el .txt archivo contiene 2,5 millones de palabras3.

Esta es la razón por la que yo no soy simplemente copiar el contenido de la .archivo txt en el .scpt archivo en sí, a pesar del hecho de que el archivo de texto es estática del 100% y nunca va a ser alterado. Insertar el texto directamente en mi script traerá consigo un considerable retraso y lentitud como puedo editar y compilar mi .scpt archivo en el Editor de secuencias de Comandos.app.

Editor De Secuencias De Comandos.la aplicación se congeló cada vez que traté de leer la .archivo txt. El problema es que el Editor de secuencias de Comandos lee en la memoria de un determinado archivo de texto en su totalidad, en lugar de la transmisión de los contenidos de una manera más eficiente. Así que, se me rompió este archivo de texto en 10 pequeños archivos de texto4, cada uno de los nuevos .archivo txt que contiene alrededor de 250.000 palabras.

En 250.000 palabras, por supuesto, los archivos de texto son todavía muy grandes (por cualquier estándar).

Aquí es un (severamente condensada) ejemplo de lo que el contenido de cada archivo de texto se ve como:

{{"exaltation","accolade","adulation","advance","advancement"},{"exalted","winnowing","winsome"},{"exam","audition","libro azul","examen","examen","final","examen","prueba","prueba","tripos","viva","escrito","examen escrito"},{"examen","La prueba de papanicolaou","método Socrático","emisión","análisis","diagnóstico anatómico","evaluación","trabajo","escrito","escrito examination"},{"examine","air","analyze","appraise","archetype","asleep","assess","canvass","case"},{"examiner","analyst","analyzer","asker"},{"examining","analytic","examinational","exploratory"},{"example","admonishment","admonition","alarm","archetype"},{"exasperate","bedevil","vex","trabajo up","worry"},{"exasperated","aggravated","amplified","angry","annoyed"},{"exasperating","annoying","bothering","bothersome"}}

Como se puede ver, el contenido del archivo de texto es una lista anidada5 que está organizado de la misma manera que AppleScript formatos de una list. Cada archivo de texto no contiene saltos de línea y párrafos.

Estoy buscando un método para obtener esta lista en mi AppleScript, con la menor latencia posible6. Esta es la razón por la que me pre-formateado. Así, la velocidad es la clave.


Notas a pie de página:

1.Mi diccionario de sinónimos secuencia de comandos es similar a la incorporada en el diccionario de sinónimos característica que existe en Microsoft Word. Una diferencia notable es que mi script funciona todo el sistema.

2.Por cierto la lista, me refiero a que puedo llamar, por ejemplo, item 12 de esta lista más adelante en mi AppleScript.

3.Mi fuente para el diccionario de datos es Grady Ward "Moby" diccionario de Sinónimos. He encontrado esta base de datos a partir de esta respuesta: Buscando Sinónimos de Datos de Stack Overflow

4.Tuve que usar Hex Demonio.aplicación para cortar desde el archivo de texto y pegarlo en un nuevo archivo de texto. No pude editar el archivo en el editor de texto.aplicación, sin TextEdit congelación en mí.

5.El exterior de la lista contiene cada entrada del diccionario de sinónimos. El interior de las listas contienen todos los sinónimos para esa entrada. El primer elemento de cada lista interna es el título de la entrada. Tanto el exterior de la lista y cada lista interna están ordenados por orden alfabético (con la excepción de la primera palabra de cada lista interna, porque, de nuevo, esta palabra es el título de la entrada).

6.Entiendo que incluso el método más rápido todavía tiene varios segundos de latencia, ya que el archivo de texto es tan grande.


1voto

user3439894 Puntos 5883

Obviamente, no sé el alcance total de lo que estás haciendo o cómo tienen otras cosas codificado, ya que no se han suministrado todos los detalles y el código, sin embargo, me gustaría tomar un enfoque diferente.

He descargado el Moby diccionario de Sinónimos de la página vinculada en su pregunta y preformado de las siguientes acciones.

  1. Extrae el contenido de la mthes.tar.Z archivo.
  2. Abrió la ./mthes/mobythes.aur archivo en TextWrangler y notó dos cosas a cambio.
    • Cambiar los finales de línea desde el Clásico Mac (CR) para Unix (LF).
    • Eliminado no deseado comas finales de 6 líneas.

Tenga en cuenta que mientras que yo podría hacer estos cambios en TextWrangler, sin embargo yo prefiero usar el Terminal, y lo hizo utilizando el siguiente comando:

tr "\r" "\n" < mobythes.aur | sed -E 's/[,]{1,}$//' > mobythes.txt

Que tuvo, pero literalmente un segundo (como yo en realidad prologado el comando anterior time, por curiosidad). Con la mobythes.aur archivo de haber sido procesado, salvó a mobythes.txt y se copian en la carpeta mis Documentos, voy a utilizar este nuevo llanura archivo CSV como es, para la consulta de la cadena de búsqueda de una coincidencia que el primer campo de cada registro y devolver el expediente, sin el primer campo, como una lista para elegir en AppleScript. He encontrado que este método es muy rápido, mientras que la búsqueda para "acercar" el último registro en el archivo CSV, pero tomó un segundo para regresar y crear la lista para que grabar sobre la marcha.

En el Editor AppleScript puedo usar el siguiente código para probar en contra de la llanura archivo CSV como un solo archivo, que contiene la 30,260 líneas con 2,5 millones de sinónimos y palabras relacionadas.

set AppleScript's text item delimiters to ""
set theMobyThesaurus to POSIX path of (path to documents folder) & "mobythes.txt"

set theSearchString to the text returned of (display dialog "Find synonyms for:" default answer "" buttons {"Cancel", "Search"} default button 2 with title "Search Moby Thesaurus")

if theSearchString is not equal to "" then

    try
        set theSearchResults to (do shell script "grep -i -m 1 '^" & theSearchString & ",' " & theMobyThesaurus)
    on error
        display dialog "No match for \"" & theSearchString & "\" available." buttons {"OK"} default button 1
        return
    end try

    if theSearchResults is not equal to "" then
        set AppleScript's text item delimiters to ","
        set theSynonymsList to items 2 thru -1 of text items of theSearchResults as list
        set AppleScript's text item delimiters to ""

        choose from list theSynonymsList with prompt "Choose a synonym for: " & linefeed & theSearchString
        if the result is not false then
            set theChosenWord to (item 1 of the result)
        end if
    end if

end if

En este ejemplo, suponiendo una búsqueda partido se hizo y nada cancelado, entonces el theChosenWord variable contiene ahora lo que fue elegido de la lista que aparece y se pueden procesar como necesitaba/quería.

Tenga en cuenta que este es, por supuesto, estrictamente código de ejemplo para propósitos de prueba y tendrán que ser adaptadas a su escenario de caso de uso, mientras que la incorporación de adecuado manejo de errores como sea necesario.

Creo que esta va a ser la manera más rápida, dejando la Moby diccionario de Sinónimos como un solo archivo CSV, y es probablemente más rápido que los métodos que has probado hasta ahora.

0voto

rubik's sphere Puntos 31

Yo había ideado una solución antes de user3439894 había publicado su respuesta.

A pesar del hecho de que user3439894's de la solución es superior a mi de la solución en todos los sentidos, me imagino que puedo puedo publicar mi código, si por ninguna otra razón que para resaltar el rápido tiempo de respuesta de user3439894's solución.


Archivo de ajustes:

Aquí están las dos modificaciones que he realizado para el archivo de origen, mobythes.aur, para mi solución:

  1. He convertido el .aur archivo .archivo txt, simplemente por el cambio de nombre de la extensión de archivo en el Finder.

  2. He insertado (1) retorno de carro delante del primer carácter de la .archivo txt (sólo en caso de que el usuario cada vez busca la primera entrada del diccionario de sinónimos, es decir, a cappella).

Me di cuenta de que yo estaba ladrando al árbol equivocado en mi post original-no es necesario (o beneficio) de pre-formato de el .txt archivo de contenido en AppleScript s list formato, dentro del propio archivo. Por lo tanto, yo no modifica el archivo original del delimitador de la estructura de ningún tipo (en la forma en que yo lo había hecho en mi post original).


Mi código:

display dialog "Find synonyms of:" default answer ""
set theSearchQuery to text returned of the result

-- Referencing the default delimiters of the "mobythes.txt" file:
set theOuterListDelimiter_oneCarriageReturn to (ASCII character 13)
set theInnerListDelimiter_oneComma to ","

set theSearchQueryAsAThesaurusEntry to (theOuterListDelimiter_oneCarriageReturn & theSearchQuery & theInnerListDelimiter_oneComma)

set theThesaurusAsString to (read POSIX file "/Users/Me/Desktop/mobythes.txt")

if theThesaurusAsString contains theSearchQueryAsAThesaurusEntry then

    set theSynonymsAsText to extractBetween(theThesaurusAsString, theSearchQueryAsAThesaurusEntry, theOuterListDelimiter_oneCarriageReturn)
    set theSynonymsInList to splitStringIntoList(theSynonymsAsText, theInnerListDelimiter_oneComma)

    choose from list theSynonymsInList
else
    display dialog "No thesaurus entry exists for \"" & theSearchQuery & "\"!"
end if


-- Subroutines:

to extractBetween(SearchText, startText, endText)
    --  Source: http://macscripter.net/viewtopic.php?id=24725
    set tid to AppleScript's text item delimiters -- save them for later.  
    set AppleScript's text item delimiters to startText -- find the first one.  
    set endItems to text of text item -1 of SearchText -- everything after the first.  
    set AppleScript's text item delimiters to endText -- find the end one.  
    set beginningToEnd to text of text item 1 of endItems -- get the first part.  
    set AppleScript's text item delimiters to tid -- back to original values.  
    return beginningToEnd -- pass back the piece.  
end extractBetween

on splitStringIntoList(theString, theDelimiter)
    -- Source: http://erikslab.com/2007/08/31/applescript-how-to-split-a-string/
    -- save delimiters to restore old settings:
    set oldDelimiters to AppleScript's text item delimiters
    -- set delimiters to delimiter to be used:
    set AppleScript's text item delimiters to theDelimiter
    -- create the array:
    set theArray to every text item of theString
    -- restore the old setting:
    set AppleScript's text item delimiters to oldDelimiters
    -- return the result:
    return theArray
end splitStringIntoList

Tiempo de ejecución de comparación de rendimiento:

Por curiosidad, he llevado a cabo un "shoot-out" de los tiempos de ejecución entre user3439894's enfoque y mi enfoque.

Me comentó que cada diálogo en ambas de nuestras soluciones. I conjunto de la prueba el término de búsqueda como la cadena fija, "planet".

Entrando time osascript /Users/Me/Desktop/MyOriginalSolution.scpt en la Terminal.la aplicación devuelve:

real    0m1.257s
user    0m0.728s
sys     0m0.409s

Entrando time osascript /Users/Me/Desktop/user3439894Solution.scpt volvió:

real    0m0.250s
user    0m0.193s
sys     0m0.030s

Basándose en esta prueba, user3439894's solución es más de 5 veces más rápido que el mío, con una diferencia de 1.007 segundos.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X