2011-07-29 11 views
7

Actualización: Solución continuaciónAppleScript: ¿Cómo comprobar si algo es un directorio o un archivo


Digamos que usted tiene una lista de elementos seleccionados de Finder. Supongamos que hay algunos archivos, carpetas, varios paquetes e incluso algunas aplicaciones incluidas en la selección.

Ahora diga que solo quiere aquellos artículos que son (en términos UNIX) directorios. Es decir. solo desea elementos que pueda cd en la terminal.

Puede comprobar la propiedad de cada elemento kind y ver si es igual a "carpeta", pero eso no funciona para paquetes de aplicaciones u otros bundles/paquetes, aunque en realidad son "carpetas" (directorios)

Si los elementos son objetos de archivo reales (no alias), puede verificar la propiedad class de cada elemento ... excepto que tampoco siempre funciona, ya que los paquetes ahora son instancias de "archivo de documento" y las aplicaciones son instancias de "archivo de aplicación".

Es peor si solo tiene una lista de alias en lugar de objetos de archivo reales, ya que no puede verificar la propiedad class; siempre solo dirá "alias".

Las únicas soluciones que puedo pensar son obtener la ruta POSIX de cada elemento y ver si tiene una barra inclinada hacia adelante, o enviar su ruta a una secuencia de comandos escrita en un idioma diferente, que puede verificar si algo es un directorio o no.

Ambas ideas me parecen locas. La comprobación de una barra inclinada hacia adelante es extremadamente hacky y frágil, y alimentar todo a una secuencia de comandos diferente es una exageración completa.


Actualización: Lo Asmus sugiere a continuación no parece ser la única una buena solución , ya que parece que no hay manera de AppleScript para resolverlo por su propia :

do shell script "file -b " & filePosixPath 

Eso devolverá el "directorio" de la cadena para carpetas, paquetes, aplicaciones, paquetes, etc. etc.
Pero tenga en cuenta (!) Que para los discos, devuelve "directorio adhesivo".

Aquí es una función generalizada que funciona bastante bien

on isDirectory(someItem) -- someItem is a file reference 
    set filePosixPath to quoted form of (POSIX path of (someItem as alias)) 
    set fileType to (do shell script "file -b " & filePosixPath) 
    if fileType ends with "directory" then return true 
    return false 
end isDirectory 
+2

Bueno, yo diría que la solución más fácil es para pasar rutas POSIX a la herramienta de línea de comandos 'archivo', donde, por ejemplo, 'file -b/Applications/Safari.app' simplemente devuelve" directorio ". Debería ser bastante fácil incorporar eso en un bucle 'do shell script'. – Asmus

+0

@Asmus: Probablemente tengas razón. Después de escribir la pregunta, me di cuenta de que podía hacer un comando rápido de shell en lugar de un script de shell completo. Aún así, parece extraño tener que salir de AppleScript para descubrir algo tan básico como si algo es un directorio o no. Dejaré la pregunta por un día más o menos, y mientras tanto, siéntete libre de escribir tu comentario como respuesta para que puedas obtener los puntos :) – Flambino

+0

@Flambino No puedo dejar de votar tu buena pregunta porque utilicé todo mi votos arriba! :( – fireshadow52

Respuesta

6

Hay una solución sencilla applescript. Puede verificar si algo es un "paquete" usando eventos del sistema.

tell application "Finder" to set theItems to (selection) as alias list 

set canCDItems to {} 
tell application "System Events" 
    repeat with anItem in theItems 
     if anItem is package folder or kind of anItem is "Folder" or kind of anItem is "Volume" then 
      set end of canCDItems to contents of anItem 
     end if 
    end repeat 
end tell 
return canCDItems 
+0

¡Interesante! Es extraño que ese vocabulario esté enterrado en System Events en lugar de Finder, pero al menos existe. Terminé usando la solución de Asmus, pero tu respondiste la pregunta original, así que ten el consejo (y marca de verificación). ¡Gracias! – Flambino

+2

Hola. System Events se creó para quitar la carga del Finder. Básicamente, el Buscador a menudo está ocupado con tareas relacionadas con la computadora, por lo que es mejor pedirle a los eventos del sistema que hagan cosas en lugar del Buscador cuando sea posible. Como tales, los eventos del sistema pueden hacer la mayoría de las cosas que el Finder puede hacer y, a veces, incluso más. Yo sugeriría que cada vez que piense en usar Finder compruebe si los eventos del sistema pueden hacerlo en su lugar. – regulus6633

+0

Gracias por la información de fondo. No sabía que esa era la génesis de los eventos del sistema, pero tiene mucho sentido. Echaré un vistazo más de cerca al diccionario de los eventos del sistema ahora. ¡Muy agradecido! – Flambino

0

Necesitaba esto hoy en día, ya que estaba tratando de conectar un par de herramientas de diferenciación en Buscador de león de montaña y quería comprobar si el artículo o artículos seleccionados fueron carpetas o archivos. Esto funcionó para mí:

tell application "Finder" 
    set sel1 to the selection 
    set class1 to class of (item 1 of sel1) 
    set cs to (class1 as string) 
    ... 
    if cs = "folder" or cs contains "class cfol" then 
    set choice to display alert "Which tool?" buttons {"opendiff", "diffmerge"} 
    set tool to (button returned of choice) 

me pareció que tenía que probar cs para ambos casos, dependiendo de si yo estaba corriendo en el Editor de AppleScript o como resultado de hacer clic en un botón de barra de herramientas en el Finder.Lejos de las más limpias, pero, más corta que la solución sólo AppleScript anterior, esta sería mi propuesta alternativa

on isDirectory(someItem) 
    ((class of someItem) as string) contains "fol" 
end isDirectory 

Los resultados del ensayo completo en todas las circunstancias dan la bienvenida!

1

Si la variable es simplemente una cadena, utilice este formulario:

on isDirectory(someItem) -- someItem is a string 
    set filePosixPath to quoted form of (POSIX path of someItem) 
    set fileType to (do shell script "file -b " & filePosixPath) 
    if fileType ends with "directory" then return true 
    return false 
end isDirectory 
0

adiciones estándar ofrece esto (no hay eventos del sistema es necesario):

set isBundleType to package folder of (info for (choose file)) 
Cuestiones relacionadas