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 suffixDas Backup-Suffix ist
~, sofern nicht mit--suffixfestgelegt oderSIMPLE_BACKUP_SUFFIX. Die Versionskontrollmethode kann über den--backupausgewählt werden Option oder überVERSION_CONTROLUmgebungsvariable. Hier sind die Werte:
none,off:niemals Sicherungskopien erstellen (selbst wenn--backupgegeben)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;-)