Ich habe nur eingeschränkte Funktionalitätstests durchgeführt, seien Sie also bitte vorsichtig mit diesem Befehl (--dry-run):
rsync -avPr --ignore-existing --remove-source-files src/ dest
Bitte beachten Sie das abschließende /, da dies in src rekursiv wird, anstatt src selbst zu kopieren, dies sollte Ihre bestehenden Pfade beibehalten.
Durch die Verwendung des Flags --ignore-existing in Kombination mit dem Flag --remove-source-files löschen Sie nur Dateien aus src, die von src nach dest synchronisiert werden, d. h. Dateien, die zuvor nicht nur in dest existierten.
Um nicht synchronisierte Dateien zu löschen, das heißt solche, die bereits in dest/ wie in src/ existierten, können Sie Folgendes verwenden:
for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done
oder
find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;
wenn Dateinamen Leerzeichen/neue Zeilen/… enthalten könnten. Bezüglich Gilles' Kommentar zu Sonderzeichen, das ist sicherlich etwas, das man beachten sollte, und es gibt viele Lösungen, die einfachste wäre, ein -i an rm zu übergeben, das vor dem Löschen auffordert. Vorausgesetzt, dass src/ oder sein übergeordneter Pfad bereitgestellt wird, um zu finden, sollte der vollständig qualifizierte Pfad jedoch dazu führen, dass alle Dateinamen sowohl von den Befehlen diff als auch rm ohne Anführungszeichen korrekt behandelt werden.
Unisono ist das Werkzeug, das Sie suchen. Probieren Sie unison-gtk aus, wenn Sie eine GUI bevorzugen. Aber ich glaube nicht, dass ähnliche Dateien gelöscht werden:Versuchen Sie gemeinsam, beide Verzeichnisse identisch zu haben. Trotzdem wird es leicht 1) identifizieren, welche Dateien kopiert werden sollen; 2) welche müssen manuell zusammengeführt werden.
Das folgende Skript sollte die Dinge vernünftig erledigen. Es verschiebt Dateien von der Quelle zum Ziel, überschreibt niemals eine Datei und erstellt bei Bedarf Verzeichnisse. Quelldateien, die eine entsprechende andere Datei im Ziel haben, werden in Ruhe gelassen, ebenso wie Dateien, die keine regulären Dateien oder Verzeichnisse sind (z. B. symbolische Links). Die Dateien, die in der Quelle übrig bleiben, sind diejenigen, für die ein Konflikt besteht. Achtung, ich habe es überhaupt nicht getestet.
cd src
find . -exec sh -c '
set -- "/path/to/dest/$0"
if [ -d "$0" ]; then # the source is a directory
if ! [ -e "$1" ]; then
mv -- "$0" "$1" # move whole directory in one go
fi
elif ! [ -e "$0" ]; then # the source doesn't exist after all
: # might happen if a whole directory was moved
elif ! [ -e "$1" ]; then # the destination doesn't exist
mv -- "$0" "$1"
elif [ -f "$1" ] && cmp -s -- "$0" "$1"; then # identical files
rm -- "$0"
fi
' {} \;
Ein anderer Ansatz wäre, ein Verzeichnis übereinander zu mounten, zum Beispiel mit funionfs oder unionfs-fuse.