GNU cp(1)
hat eine Sicherungsoption:
cp --backup SOURCE [SOURCE...] [DESTINATION]
Dies hat die folgenden Effekte, die mit anderen Optionen gesteuert werden können, wie in der Handbuchseite von cp(1)
beschrieben :
--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
Das Backup-Suffix ist
~
, sofern nicht mit--suffix
festgelegt oderSIMPLE_BACKUP_SUFFIX
. Die Versionskontrollmethode kann über den--backup
ausgewählt werden Option oder überVERSION_CONTROL
Umgebungsvariable. Hier sind die Werte:
none
,off
:niemals Sicherungskopien erstellen (selbst wenn--backup
gegeben)numbered
,t
:nummerierte Backups erstellenexisting
,nil
:nummeriert, falls nummerierte Backups existieren, sonst einfachsimple
,never
:Immer einfache Backups erstellen
Beispiel
cp --backup=existing --suffix=.orig ~/Music/* ~/Videos
Dadurch werden alle Dateien in ~/Music
kopiert bis ~/Videos
. Existiert am Zielort eine gleichnamige Datei, wird diese durch Anhängen von .orig
umbenannt zu seinem Namen als Backup. Wenn eine Datei mit demselben Namen wie die Sicherung vorhanden ist, wird die Sicherung stattdessen umbenannt, indem .1
angehängt wird und, falls auch vorhanden, .2
und so weiter. Erst dann wird die Quelldatei zum Ziel kopiert.
Wenn Sie Dateien in Unterverzeichnissen rekursiv kopieren möchten, verwenden Sie -R
:
cp -R --backup=existing --suffix=.orig ~/Music ~/Videos
Ihr Problem besteht eigentlich darin, einen cp
zu finden Variante, die die Zieldatei unter einem anderen Namen erstellt, falls sie bereits existiert. Mir ist kein Tool bekannt, das dies tut, aber es ist nicht schwer, es selbst zu implementieren:
cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"
Dieses Skript ruft cp
auf Falls dies fehlschlägt, wird die Prüfsumme erneut an den Dateinamen angehängt. Fehler:Wenn eine dritte Datei mit demselben Namen auftaucht, wird die zweite Datei wenn sie identisch sind überschrieben .
Vorausgesetzt, das obige Skript heißt saveCopy
und im übergeordneten Arbeitsverzeichnis gespeichert, funktioniert Folgendes:
$ 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
Beachten Sie, dass das Skript nur für eine einzelne Eingabedatei funktioniert und wenn das Ziel ein Verzeichnis ist! Es kann sicherlich verbessert werden;-)