2 votes

Comment puis-je reproduire l'ordre de tri du Finder sans demander au Finder de trier pour moi ?

Je travaille avec une grande collection de fichiers principalement textuels subdivisés par séries, les reproduisant périodiquement à partir d'un dépôt en amont et les reconditionnant à l'aide d'un shell script à partir d'une organisation de sources légèrement chaotique vers des formes plus ordonnées et compactes. Les sources sont rassemblées dans des répertoires de fichiers pour chaque série, allant d'une poignée à des centaines par série, avec une convention de nommage semi-ordonnée et orientée vers l'humain datant des années 90 avec ce modèle général :

nom de la série multi-mots[-$subsetnumber]-$docnumber[.{txt,html,pdf}]

Une série peut avoir ou non des sous-ensembles, les sous-ensembles peuvent être numérotés avec des chiffres romains ou arabes, une série peut commencer avec des documents numérotés dans aucun sous-ensemble et obtenir plus tard un sous-ensemble étiqueté "II" ou "2", et ainsi de suite. Ces noms fonctionnent bien pour les personnes qui les utilisent à partir du Finder, qui, dans la plupart des cas, les ordonne de manière humaine et détecte que le nom-II-1 vient après le nom-6 et que le nom-2 ne vient pas après le nom-19. Comme mon reconditionnement consiste à assembler la dernière version de chaque série dans des fichiers uniques dans leur ordre rationnel, j'utilise un simple bout d'AppleScript qui utilise le Finder pour trier les noms des éléments dans un répertoire donné. Cela donne des résultats corrects, mais c'est spectaculairement inefficace pour des raisons que je ne comprends pas. L'AppleScript est le suivant :

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

(Et non, je ne me souviens pas de la raison pour laquelle j'ai procédé ainsi. Je l'ai écrit vers 2008 et je déteste surtout AppleScript...) Ceci est compilé dans un script nommé "flist.scpt" et exécuté depuis mon shell script avec "osascript flist.scpt /path/to/series/folder/". Le résultat de l'exécution de ce script avec un répertoire contenant 26 fichiers est de faire tourner le processeur pendant plus de 2 minutes. À titre de comparaison, "ls" donne des résultats triés lexicalement sur la même machine (un iMac G5 fonctionnant sous Leopard... ne riez pas, c'est une machine utilitaire) en 0,008 seconde. avec le script en arrière-plan dans le même répertoire.

Je cherche à me débarrasser complètement de cet AppleScript, mais je n'ai pas trouvé de moyen de reproduire facilement la logique de tri du Finder, c'est-à-dire en définissant une locale ou en donnant des arguments complexes à 'sort' qui ordonneront les noms correctement. Ma solution de repli, si je ne trouve pas quelque chose d'original, sera de reproduire moi-même la logique du Finder dans un mélange diabolique de sort, sed, awk et shell, mais j'aimerais vraiment éviter cela dans la mesure du possible. S'il y a quelque chose de bizarre dans mon AppleScript qui est à l'origine des performances horribles, le corriger serait presque aussi bien qu'une incantation magique à 'ls' pour qu'il trie comme le Finder.

MISE À JOUR : RÉSOLU ! J'ai d'abord essayé le module Perl Sort::Naturally, mais il triait les noms des sous-ensembles étiquetés avant les membres implicites du sous-ensemble "I", ce qui n'était pas ce que je voulais. Je me suis donc lancé dans l'écriture de mon premier script Ruby, après avoir modifié la configuration Ruby de Leopard pour que 'gem' fonctionne dans le monde moderne et installé la gem naturalsort. Le script de remplacement en Ruby (appelé avec un nom de répertoire comme argument) est :

#! /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)

Les différences mineures dans la sortie sont que ceci inclut les entrées . et .. et délimite les entrées par ligne plutôt que par des espaces, mais comme ceci est appelé depuis un shell script qui filtre déjà certains noms spéciaux, ces différences sont triviales à gérer.

2voto

Fuzzy Purple Monkey Points 702

L'ordre de tri exact utilisé par Finder dépend probablement de la locale, mais les langages de script comme Ruby et Python disposent de bibliothèques permettant de trier naturellement les chaînes de caractères.

#!/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)

0voto

adayzdone Points 1798

Construction d'une chaîne de caractères à l'aide de

set a to a & b

n'est pas aussi rapide que de construire une liste et de la contraindre à écrire un texte à la fin.

Essayez :

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

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X