GNU cp(1)
tiene una opción de respaldo:
cp --backup SOURCE [SOURCE...] [DESTINATION]
Esto tiene los siguientes efectos que se pueden controlar con otras opciones como se describe en la página del manual de 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
El sufijo de respaldo es
~
, a menos que se establezca con--suffix
oSIMPLE_BACKUP_SUFFIX
. El método de control de versiones se puede seleccionar a través del--backup
opción o mediante elVERSION_CONTROL
Variable ambiental. Estos son los valores:
none
,off
:nunca haga copias de seguridad (incluso si--backup
se da)numbered
,t
:hacer copias de seguridad numeradasexisting
,nil
:numerado si existen copias de seguridad numeradas, simple de lo contrariosimple
,never
:siempre haga copias de seguridad simples
Ejemplo
cp --backup=existing --suffix=.orig ~/Music/* ~/Videos
Esto copiará todos los archivos en ~/Music
a ~/Videos
. Si existe un archivo con el mismo nombre en el destino, se le cambia el nombre agregando .orig
a su nombre como respaldo. Si existe un archivo con el mismo nombre que la copia de seguridad, se cambia el nombre de la copia de seguridad agregando .1
y, si eso también existe, .2
Etcétera. Solo entonces se copia el archivo de origen en el destino.
Si desea copiar archivos en subdirectorios de forma recursiva, use -R
:
cp -R --backup=existing --suffix=.orig ~/Music ~/Videos
Su problema es en realidad encontrar un cp
variante que crea el archivo de destino con un nombre diferente si ya existe. No conozco una herramienta que lo haga, sin embargo, no es difícil implementarlo usted mismo:
cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"
Este script llama a cp
nuevamente en caso de que falle, agregando la suma de verificación al nombre del archivo. Defecto:si aparece un tercer archivo con el mismo nombre, sobrescribirá el segundo archivo si son idénticos .
Dado que el script anterior se llama saveCopy
y almacenado en el directorio de trabajo principal, lo siguiente funciona:
$ 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
¡Tenga en cuenta que el script solo funciona para un único archivo de entrada y si el destino es un directorio! Ciertamente se puede mejorar;-)