Per spostare file con nomi duplicati conservando entrambe le copie, assegnare a ogni file in arrivo un nome di destinazione non utilizzato prima di spostarlo. Questa guida crea una scorciatoia Mac che aggiunge suffissi numerati, utilizzando file di testo usa e getta per dimostrare il risultato.

L'attività consiste nello spostare file ordinari da una cartella locale a un'altra che potrebbe già contenere nomi corrispondenti. I file esistenti nella destinazione rimangono al loro posto; i file in arrivo ricevono nomi come notes (2).txt. Conservare entrambi significa mantenere entrambi i file nella destinazione dopo lo spostamento: il file in arrivo non rimane più nella cartella di origine.

Cosa documenta Apple sulla conservazione di entrambi i file?

Apple documenta il supporto per l'esecuzione di script shell direttamente all'interno di Scorciatoie. Le pagine pubbliche di Scorciatoie citate qui non specificano una politica di collisione Keep Both per l'azione Move File. Invece di dipendere da un'impostazione non documentata, questo flusso di lavoro prende la decisione di denominazione esplicitamente in Run Shell Script. Apple descrive la capacità di scripting in Meet Shortcuts for macOS.

Il comando macOS sottostante ha un comportamento documentato più ristretto: mv -n non sovrascrive un file esistente. Non genera un nuovo nome. Di conseguenza, questa scorciatoia necessita sia di un ciclo di selezione del nome file che dell'opzione di non sovrascrittura. Si tratta di responsabilità separate, come mostrato nella sorgente manuale mv(1) pubblicata da Apple.

Anche l'unione delle cartelle nel Finder ha dei limiti. Apple afferma che Merge appare solo quando una cartella contiene elementi assenti nell'altra; le cartelle contenenti versioni diverse di file con nomi identici offrono Stop o Replace. L'unione delle cartelle non fornisce quindi il comportamento di file numerati necessario qui. Vedi Organizzare i file nelle cartelle su Mac.

Preparare un esempio usa e getta con nomi duplicati

Utilizzare questo esempio con due cartelle sullo stesso disco locale. Gestisce file ordinari, non nascosti, direttamente all'interno della cartella di origine. Non elabora ricorsivamente le sottocartelle, non sposta alias o collegamenti simbolici, né unisce pacchetti. Eseguire un'istanza alla volta, senza che nessuna delle cartelle venga modificata da un altro processo.

La scorciatoia richiede che Run Shell Script sia disponibile ed eseguibile sul tuo Mac. Se quell'azione non può essere eseguita nella tua configurazione, utilizza la procedura del Finder descritta più avanti in questo articolo. Gli esempi seguenti non richiedono software aggiuntivo.

Apri Terminale e incolla questo comando di configurazione completo. Crea una nuova cartella Scrivania contenente solo testo sintetico. Se Shortcuts-name-demo esiste già, il comando si interrompe invece di riutilizzarne il contenuto.

/bin/bash <<'BASH'
set -e
root="$HOME/Desktop/Shortcuts-name-demo"
/bin/mkdir "$root"
/bin/mkdir "$root/Incoming" "$root/Collected"
printf '%s\n' 'Incoming synthetic notes.' > "$root/Incoming/notes.txt"
printf '%s\n' 'Existing synthetic notes.' > "$root/Collected/notes.txt"
printf '%s\n' 'Earlier synthetic second copy.' > "$root/Collected/notes (2).txt"
printf '%s\n' 'Synthetic readme.' > "$root/Incoming/readme.txt"
printf 'Example folder: %s\n' "$root"
BASH

La collisione è intenzionale: la destinazione contiene già sia notes.txt che notes (2).txt. Una scorciatoia che si limita ad aggiungere (2) incontrerebbe un'altra collisione. La regola decisionale utile consiste nel testare candidati successivi finché non se ne trova uno disponibile.

Per facilitare l'ispezione, attiva Mostra tutte le estensioni dei nomi file in Finder > Impostazioni > Avanzate. Apple spiega che nascondere un'estensione ne cambia la visualizzazione, mentre cambiare l'estensione stessa può influire sull'app che apre il file. Mantieni .txt invariato in questo esempio. Vedi Mostrare o nascondere le estensioni dei nomi file su Mac.

Creare la scorciatoia con gestione esplicita delle collisioni

Crea una scorciatoia utilizzando il pulsante Aggiungi in Scorciatoie e chiamala Move Files and Keep Both. Trova Run Shell Script nella libreria delle azioni e aggiungilo. Apple documenta la creazione di scorciatoie e l'aggiunta di azioni in Creare una scorciatoia personalizzata su Mac.

Imposta la shell dell'azione su /bin/bash, quindi sostituisci lo script di esempio con il programma completo riportato di seguito. Questa versione legge i due percorsi delle cartelle dalle variabili nello script. Non consuma l'input della scorciatoia, gli elementi selezionati nel Finder o l'input standard, quindi l'impostazione di passaggio dell'input è irrilevante.

set -e
shopt -s nullglob

src_dir="$HOME/Desktop/Shortcuts-name-demo/Incoming"
dst_dir="$HOME/Desktop/Shortcuts-name-demo/Collected"

fail() {
    printf '%s\n' "$1" >&2
    exit 1
}

[[ -d "$src_dir" ]] || fail "Source folder does not exist."
[[ -d "$dst_dir" ]] || fail "Destination folder does not exist."

src_dir=$(cd "$src_dir" && pwd -P)
dst_dir=$(cd "$dst_dir" && pwd -P)
[[ "$src_dir" != "$dst_dir" ]] || fail "Choose different folders."

moved=0
for src in "$src_dir"/*; do
    if [[ -L "$src" || ! -f "$src" ]]; then
        printf 'Skipped non-regular item: %s\n' "$src" >&2
        continue
    fi

    name=${src##*/}
    stem=$name
    ext=
    if [[ "$name" == *.* && "$name" != .* && "$name" != *. ]]; then
        stem=${name%.*}
        ext=.${name##*.}
    fi

    target="$dst_dir/$name"
    number=2
    while [[ -e "$target" || -L "$target" ]]; do
        target="$dst_dir/$stem ($number)$ext"
        number=$((number + 1))
    done

    /bin/mv -n "$src" "$target" || fail "Move failed: $src"
    if [[ -e "$src" || -L "$src" || ! -f "$target" ]]; then
        fail "Move was not completed as expected: $src"
    fi

    moved=$((moved + 1))
    printf 'Moved: %s -> %s\n' "$name" "${target##*/}"
done
printf 'Completed: %s file(s) moved.\n' "$moved"

Aggiungi Quick Look dopo l'azione script per ispezionarne il report. Apple raccomanda specificamente di inserire Quick Look durante i test per vedere quale contenuto fluisce tra le azioni. Vedi Testare le azioni in Scorciatoie su Mac.

Il report contiene testo che descrive gli spostamenti completati. Non è un elenco di oggetti File spostati. Se in seguito estendi la scorciatoia, non trattare quelle righe del report come input file. Apple documenta che le azioni accettano e producono tipi di contenuto particolari; usa Mostra info su un'azione per ispezionarne l'input accettato e l'output risultante. Vedi Connessioni tra azioni in Scorciatoie su Mac.

In che modo la regola di denominazione preserva entrambe le copie?

Per ogni file di origine, lo script controlla innanzitutto il percorso di destinazione originale. Se quel percorso è occupato, prova (2), poi (3), continuando finché un candidato non è libero. Anche le directory e i collegamenti simbolici esistenti contano come nomi occupati. Lo spostamento finale usa mv -n come ulteriore controllo di non sovrascrittura, seguendo la documentazione mv(1) di Apple.

Incoming file Destination already contains Chosen destination name
notes.txt Nothing with that name notes.txt
notes.txt notes.txt notes (2).txt
notes.txt notes.txt, notes (2).txt notes (3).txt
readme readme readme (2)
archive.tar.gz archive.tar.gz archive.tar (2).gz

Queste sono le regole di denominazione del programma, non un'affermazione sulla denominazione automatica del Finder. Solo l'estensione finale viene separata: .gz rimane alla fine di archive.tar (2).gz. Un file in arrivo già denominato notes (2).txt mantiene quello stem, producendo notes (2) (2).txt se necessario. Lo script non interpreta un numero esistente come una versione.

Il programma mette tra virgolette i percorsi e itera sui nomi file espansi dalla shell invece di dividere un elenco di testo. I nomi contenenti spazi rimangono quindi elementi singoli. La sua sintassi usa deliberatamente Bash; mantieni /bin/bash selezionato. Nozioni di base sugli script shell di Apple spiega perché le differenze tra dialetti shell sono importanti.

Eseguire l'esempio e verificare il risultato

Esegui la scorciatoia una volta, quindi ispeziona entrambe le cartelle nel Finder. Per i dati sintetici forniti, il contenuto previsto della destinazione è:

  • notes.txt, ancora contenente Existing synthetic notes.
  • notes (2).txt, ancora contenente Earlier synthetic second copy.
  • notes (3).txt, contenente Incoming synthetic notes.
  • readme.txt, contenente Synthetic readme.

La cartella Incoming dovrebbe ora essere vuota, e il report dovrebbe terminare con Completed: 2 file(s) moved. Eseguendo nuovamente la scorciatoia senza aggiungere file, dovrebbe essere riportato zero spostamenti. Questi sono i risultati previsti per l'esempio; il flusso di lavoro completo di macOS Shortcuts non è stato eseguito durante la preparazione di questo articolo. Le espressioni di separazione dei nomi file sono state verificate separatamente con nomi sintetici.

Se la scorciatoia si interrompe, ispeziona entrambe le cartelle prima di rieseguirla. Ogni file viene spostato singolarmente, quindi un errore su un file successivo non annulla gli spostamenti precedenti. Lo script verifica se la sorgente rimane dopo ogni comando, invece di assumere che il completamento di ogni comando significhi che un file è stato spostato.

In caso di errore di spostamento ordinario, Apple consente di verificare se il file è aperto e se la destinazione ha spazio sufficiente. Vedi Se non puoi spostare o copiare un elemento su Mac. Un nome file che diventa troppo lungo dopo l'aggiunta di un suffisso può anche impedire a questo programma di completare lo spostamento; si interrompe invece di troncare il nome.

Il controllo di esistenza e lo spostamento sono operazioni separate. Questo programma è destinato a un singolo flusso di lavoro locale eseguito manualmente, con cartelle stabili. Non riserva i nomi candidati contro modifiche simultanee. Evita esecuzioni contemporanee e altri scrittori nelle cartelle di esempio.

Usare il Finder quando hai solo poche collisioni

Per un piccolo gruppo, rinomina esplicitamente il file in arrivo prima di spostarlo. Nell'esempio sintetico, ispeziona Collected, seleziona Incoming/notes.txt, premi Invio, inserisci notes (3).txt, e premi di nuovo Invio. Apple documenta questa procedura di rinomina in Rinominare file, cartelle e dischi su Mac.

Quindi trascina il file rinominato in Collected sullo stesso disco. Apple documenta il trascinamento di un elemento in una cartella per spostarlo, tenendo premuto Option per copiarlo, e tenendo premuto Command quando lo si trascina su un disco diverso per spostarlo. Vedi Organizzare i file nelle cartelle su Mac. Se appare un altro conflitto di nomi, annulla quel trasferimento e scegli un altro nome non utilizzato.

Una volta che l'esempio usa e getta si comporta come previsto sul tuo Mac, adatta solo src_dir e dst_dir per un altro paio di cartelle locali con le stesse condizioni. Mantieni insieme il ciclo di nomi numerati e i controlli di completamento: scegliere un nome non utilizzato preserva entrambe le copie nella destinazione, mentre controllare il risultato ti dice se il file in arrivo è stato effettivamente spostato.

Fonti