GNU cp(1)
ha un'opzione di backup:
cp --backup SOURCE [SOURCE...] [DESTINATION]
Questo ha i seguenti effetti che possono essere controllati con altre opzioni come descritto nella pagina di manuale di cp(1)
:
--backup[=CONTROL] make a backup of each existing destination file -b like --backup but does not accept an argument -S, --suffix=SUFFIX override the usual backup suffix
Il suffisso di backup è
~
, a meno che non sia impostato con--suffix
oSIMPLE_BACKUP_SUFFIX
. Il metodo di controllo della versione può essere selezionato tramite il--backup
opzione o attraverso ilVERSION_CONTROL
variabile d'ambiente. Ecco i valori:
none
,off
:non eseguire mai backup (anche se--backup
è dato)numbered
,t
:crea backup numeratiexisting
,nil
:numerato se esistono backup numerati, altrimenti semplicesimple
,never
:fai sempre dei semplici backup
Esempio
cp --backup=existing --suffix=.orig ~/Music/* ~/Videos
Questo copierà tutti i file in ~/Music
a ~/Videos
. Se nella destinazione esiste un file con lo stesso nome, viene rinominato aggiungendo .orig
al suo nome come backup. Se esiste un file con lo stesso nome del backup, il backup viene invece rinominato aggiungendo .1
e, se esiste anche questo, .2
e così via. Solo allora il file di origine viene copiato nella destinazione.
Se vuoi copiare i file nelle sottodirectory in modo ricorsivo usa -R
:
cp -R --backup=existing --suffix=.orig ~/Music ~/Videos
Il tuo problema è in realtà trovare un cp
variante che crea il file di destinazione con un nome diverso se esiste già. Non sono a conoscenza di uno strumento che lo faccia, tuttavia, non è difficile implementarlo da soli:
cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"
Questo script chiama cp
di nuovo in caso di errore, aggiungendo il checksum al nome del file. Difetto:se viene visualizzato un terzo file con lo stesso nome, sovrascriverà il secondo file se sono identici .
Dato che lo script precedente si chiama saveCopy
e memorizzato nella directory di lavoro principale, funziona quanto segue:
$ find . -name 'z*.jpg' -exec ./saveCopy {} /tmp/Extracted/ \;
./a/z1.jpg -> /tmp/Extracted/z1.jpg
./a/z2.jpg -> /tmp/Extracted/z2.jpg
./a/z3.jpg -> /tmp/Extracted/z3.jpg
/tmp/Extracted/z3.jpg not overwritten
./b/z3.jpg -> /tmp/Extracted//z3.jpg~d41d8cd98f00b204e9800998ecf8427e
./b/z4.jpg -> /tmp/Extracted/z4.jpg
Tieni presente che lo script funziona solo per un singolo file di input e se l'obiettivo è una directory! Può certamente essere migliorato;-)