Modifica della struttura della cartella basata su data di AppleScript

1

Ho un AppleScript che è stato scritto e funziona come tale, ma ho bisogno di cambiare il modo in cui crea la struttura delle cartelle. Lo script fa quanto segue:

  • La cartella è selezionata che contiene i file (nel mio caso saranno le foto).
  • Verrà quindi visualizzata la data di creazione delle immagini.
  • Crea una YYYY (cartella Anno se non già creata).
  • Crea un MM (cartella Mese se non già creata).
  • Crea un DD (cartella Day se non già creata).
  • Sposta quindi la foto in questa cartella e la ripete per la foto successiva e la ripete fino al completamento.

La struttura attuale della cartella viene creata come segue:

2018 "YYYY"
├── 2018-01 "MM"
├── 2018-02

Questo è fantastico e funziona come progettato, ma ho cambiato idea su come vorrei che fossero le cartelle. Vorrei la seguente struttura (che è quasi la stessa solo una diversa struttura di denominazione:

2018
├── 001 January
│   ├── 20180101
│   └── 20180102
├── 002 February
│   ├── 20180201
│   └── 20180202
└── 003 March
    ├── 20180301
    └── 20180302

Ora ho cercato di capire dove lo script genera questo, ma ho fallito, quindi ora mi sto rivolgendo a questo ottimo posto per un po 'di aiuto.

on run
    SortFiles(POSIX path of (choose folder))
end run

on open (DroppedFolder)
    set DroppedFolder to POSIX path of DroppedFolder
    if text (length of text of DroppedFolder) of DroppedFolder is not "/" then quit
    SortFiles(DroppedFolder)
end open

on SortFiles(SortFolder)
    set AppleScript's text item delimiters to return
    set SortFolderContents to the text items of (do shell script "find '" & SortFolder & "' -type f")
    set FolderMakeList to {}
    repeat with ThisItem in SortFolderContents
        set ThisFile to ThisItem as string
        if ThisFile does not contain "/." then
            tell application "Finder"
                set DateString to text 1 thru 7 of ((creation date of ((POSIX file ThisFile) as alias)) as «class isot» as string)
                set ThisFilesFolder to SortFolder & text 1 thru 4 of DateString & "/"
                set ThisFilesSubfolder to ThisFilesFolder & text 1 thru 7 of DateString & "/"
            end tell
            if ThisFilesFolder is not in FolderMakeList then
                try
                    do shell script ("mkdir '" & ThisFilesFolder & "'")
                end try
                set FolderMakeList to FolderMakeList & ThisFilesFolder
            end if
            if ThisFilesSubfolder is not in FolderMakeList then
                try
                    do shell script ("mkdir '" & ThisFilesSubfolder & "'")
                end try
                set FolderMakeList to FolderMakeList & ThisFilesSubfolder
            end if
            try
                do shell script ("mv '" & ThisFile & "' '" & ThisFilesSubfolder & "'")
            end try
        end if
    end repeat
    return FolderMakeList
end SortFiles
    
posta Adam Mann Pro 21.12.2018 - 14:46
fonte

2 risposte

3

La parte del tuo script che dà il nome alle cartelle è questa:

set ThisFilesFolder to SortFolder & (do shell script ("date -r " & ThisFilesEpoch & " \"+%b-%Y\"")) & "/"

Tuttavia, nel mio breve test del tuo script, non sembra che crei la struttura della cartella che hai descritto, il che non è una sorpresa per me dato che il comando shell usato per generare la stringa della data da cui la cartella è nominata è questa:

date -r %time% "+%b-%Y"

dove %time% è inserito tramite la variabile ThisFilesEpoch e rappresenta il numero di secondi dall'Epoch (1 gennaio 1970) che il file (o, piuttosto, il suo inode) è stato creato. Questa funzione di shell, date , prende questo valore (un numero intero grande), che è un valore in "Tempo Unix" e lo riformatta utilizzando una rappresentazione canonica come indicato dai token %b (che rappresenta un abbreviazione di tre lettere per il mese) e %Y (che rappresenta un numero di quattro cifre per l'anno).

Quindi, ad esempio:

date -r 1534615274 "+%b-%Y"

restituisce:

Aug-2018

in cui sono stati spostati i file dall'agosto 2018 che avevo nella cartella scelta. Non creava cartelle separate per il giorno del mese, né cartelle separate per anno; solo "month-year" cartelle. Quindi sono confuso dal fatto che tu abbia descritto ciò che potrebbe essere uno script completamente diverso.

Anche la sceneggiatura ha un certo numero di qualità che mi infastidiscono molto, come ad esempio:

  1. Il suo uso lazy di try ... end try ;

  2. L'inserimento di virgolette letterali che circondano una variabile utilizzata come parte di una stringa, ad es.

    do shell script "find '" & SortFolder & "' -type f" 
    

    invece di

    do shell script "find " & quoted form of SortFolder & " -type f" 
    
  3. Questa formulazione bizzarra :

    if text (length of text of DroppedFolder) of DroppedFolder is not "/" then...
    

    che potrebbe essere scritto come

    if text -1 of DroppedFolder is not "/" then...
    

    o come

    if the last character of DroppedFolder is not "/" then...
    

    o anche

    if DroppedFolder does not end with "/" then...
    
  4. E uso ripetuto di do shell script , che va bene come strumento di comando per essere invocato pensosamente quando necessario, ma quando popola lo script con la stessa densità con cui lo fa, uno si chiede perché lo script non sia stato appena scritto come script shell / bash per cominciare. È anche molto costoso in termini di spese generali per creare e distruggere i processi di shell uno dopo l'altro come fa questo script.

Considerati questi inconvenienti stilistici e funzionali, oltre alla confusione su ciò che la sceneggiatura dovrebbe fare attualmente rispetto a ciò che sembra effettivamente fare, ho ritenuto che fosse necessaria una riscrittura:

use Finder : application "Finder"
property rootdir : missing value

# The default run handler when run within Script Editor
on run
    using terms from scripting additions
        set root to choose folder
    end using terms from
    set rootdir to Finder's folder root                         -- '
    sortFiles()
end run

# Processes items dropped onto the applet.  The handler expects one or more 
# file references in the form of an alias list, and will process each item in 
# the list in turn.  If an item is not a folder reference, it is ignored.
# For the rest, the contents of each folder is reorganised.
on open droppedItems as list
    repeat with drop in droppedItems
        set rootdir to Finder's item drop
        if rootdir's class = folder then sortFiles()
    end repeat
end open

# Obtains every file in the root directory and all subfolders, moving them
# to new folders nested within the root directory and organised by year, month,
# and date of each file's creation
to sortFiles()
    repeat with f in the list of fileitems()
        set [yyyy, m, dd] to [year, month, day] of (get ¬
            the creation date of Finder's file f)               -- '

        set mmm to text -3 thru -1 of ("00" & (m * 1)) -- e.g. "008"
        set mm to text -2 thru -1 of mmm -- e.g. "08"
        set dd to text -2 thru -1 of ("0" & dd) -- e.g. "01"

        (my newFolderNamed:yyyy inFolder:rootdir)
        (my newFolderNamed:[mmm, space, m] inFolder:result)

        move Finder's file f to my newFolderNamed:[yyyy, mm, dd] ¬
            inFolder:result                                     -- '
    end repeat
end sortFiles

# A handler to house a script object that enumerates the contents of a 
# directory to its full depth
on fileitems()
    script
        property list : every document file in the ¬
            entire contents of the rootdir ¬
            as alias list
    end script
end fileitems

# Creates a new folder with the supplied name in the specified directory, 
# checking first to see whether a folder with that name already exists.  
# In either case, a Finder reference to the folder is returned.
to newFolderNamed:(dirname as text) inFolder:dir
    local dirname, dir

    tell (a reference to folder dirname in the dir) ¬
        to if it exists then return it

    make new folder at the dir with properties {name:dirname}
end newFolderNamed:inFolder:

Vi esorto a testare inizialmente questo script su una directory di test contenente file di esempio. In effetti, lo scenario peggiore è lo stesso del tuo script corrente, che è la situazione in cui hai scelto la directory sbagliata per sbaglio. Supponendo che la directory corretta sia selezionata, lo scenario peggiore è che i file non vengono spostati, quindi in genere è uno script molto sicuro.

Ho riscritto anche il open handler, per (si spera) consentirgli di gestire più elementi che vengono rilasciati sull'applet. Ciò significa che potresti, ad esempio, trascinare due cartelle su di esso e avere il contenuto di entrambe le cartelle ri-strutturato. Tuttavia, non ho provato questo. Anche in questo caso, lo scenario peggiore qui è che non fa nulla, che sarà il caso se mi sbaglio su quale tipo di riferimento al file viene passato al gestore open (presumo che sarà alias oggetti) .

    
risposta data 22.12.2018 - 10:37
fonte
0

Modifica% b,% Y ecc.

Ecco una chiave: link

    
risposta data 21.12.2018 - 17:23
fonte

Leggi altre domande sui tag