¿Cómo puedo reproducir el orden de clasificación del Finder sin pedirle que lo haga por mí?

2

Trabajo con una gran colección de archivos de texto en su mayoría subdivididos por series, duplicándolos periódicamente desde un repositorio ascendente y volviendo a empaquetarlos usando un script de shell de una organización de origen ligeramente caótica en formas más ordenadas y compactas. Las fuentes se recopilan en directorios de archivos para cada serie de números desde unos pocos hasta cientos por conjunto, con una convención de nomenclatura orientada a los seres humanos que se remonta a los años 90 con este patrón general:

multi-word-series-name [- $ subsetnumber] - $ docnumber [. {txt, html, pdf}]

Cuando una serie puede o no tener subconjuntos, los subconjuntos se pueden numerar con números romanos o árabes, una serie puede comenzar con documentos numerados en ningún subconjunto y luego obtener un subconjunto con la etiqueta "II" o "2", y así sucesivamente . Estos nombres funcionan bien para las personas que los usan desde el Finder, que en la mayoría de los casos los ordena de manera humana y detecta que el nombre-II-1 viene después del nombre-6 y que el nombre-2 no viene después del nombre-19 . Debido a que mi reenvasado consiste en ensamblar la última versión de cada serie en archivos individuales en su orden humano-racional, utilizo un fragmento simple de AppleScript que usa el Finder para ordenar los nombres de los elementos en un directorio determinado. Esto produce resultados correctos, pero es espectacularmente ineficiente por razones que no entiendo. El AppleScript es:

on run argv
    set op to ""
    set upath to POSIX file argv as string
    tell application "Finder"
        set foo to every item of folder upath
        set foo to sort foo by name
        repeat with curfile in foo
            set thisname to the name of curfile
            set op to op & " " & thisname as string
        end repeat
    end tell
    return op
end run

(Y no, no recuerdo por qué lo hice de esa manera. Lo escribí alrededor del 2008 y la mayoría odio AppleScript ...) Esto se compila en un script llamado "flist.scpt" y se ejecuta desde mi shell script con "osascript flist.scpt / ruta / a / series / carpeta /". El resultado de ejecutar ese script con un directorio que tiene 26 archivos es pegar la CPU por más de 2 minutos. A modo de comparación, 'ls' proporciona resultados ordenados léxicamente en la misma máquina (un iMac G5 que ejecuta Leopard ... no se ríe, es una máquina de utilidad) en 0.008s con el script masticando el mismo directorio en segundo plano .

Estoy tratando de deshacerme de ese AppleScript por completo, pero no he encontrado una manera de reproducir la lógica de clasificación del Finder fácilmente, es decir, al establecer una configuración regional o dar algunos argumentos complejos para "ordenar" que ordenen los nombres correctamente . Mi solución alternativa si no puedo encontrar algo enlatado para hacer esto sería reproducir la lógica del Finder yo mismo en una mezcla malvada de tipo, sed, awk y shell, pero me gustaría evitar eso si es posible. Si hay algo tonto en mi AppleScript que está causando el horrible rendimiento, arreglarlo sería casi tan bueno como un encantamiento mágico a 'ls' para que se parezca al Finder.

ACTUALIZACIÓN: ¡SOLUCIONADO! Primero probé el módulo Perl Sort :: Naturally, pero ordenó los nombres de los subconjuntos etiquetados antes de los miembros implícitos del subconjunto "I", que no es lo que quería. Así que seguí adelante y comencé a escribir mi primer script de Ruby, después de hackear un arreglo en la configuración de Leopard Ruby para hacer que la 'gema' funcionara en el mundo moderno e instalar la gema naturalsort. El script Ruby de reemplazo (llamado con un nombre de directorio como argumento) es:

#! /usr/bin/env ruby -rubygems -KU
# Largely cargo-culted from stackexchange response. 
# I dunno what exactly the shebang line opts to ruby do. Probably pwn me. 
# My first Ruby script ever. Don't laugh too hard. 

require 'natural_sort' # gem install naturalsort

dname = ARGV[0]
input = Dir.entries(dname)
puts NaturalSort.naturalsort(input)

Las diferencias menores en la salida son que esto incluye el. y .. entradas y delimita las entradas por línea en lugar de con espacios, pero como se llama desde un script de shell que ya filtra algunos nombres especiales, estos son triviales de manejar.

    
pregunta Bill Cole 08.10.2012 - 17:55

2 respuestas

2

El orden de clasificación exacto utilizado por Finder probablemente depende de la configuración regional, pero los lenguajes de script como Ruby y Python tienen bibliotecas para ordenar las cadenas de forma natural.

#!/usr/bin/env ruby -rubygems -KU

require 'natural_sort' # gem install naturalsort

input = "name-II-1
name-6
name-2
name-19".lines
# input = Dir["#{ENV['HOME']}/Documents/*"]

puts NaturalSort.naturalsort(input)
    
respondido por el user495470 08.10.2012 - 20:31
0

Construyendo una cadena usando

set a to a & b

no es tan rápido como crear una lista y obligarlo a enviar un texto al final.

Prueba:

on run argv
set op to {}
tell application "Finder" to set foo to sort every item of folder argv by name

repeat with curfile in my foo
tell application "System Events" to set end of op to name of curfile & space
end repeat
return op as text
end run
    
respondido por el adayzdone 08.10.2012 - 20:59

Lea otras preguntas en las etiquetas