Answers:
我仅执行了有限的功能测试,因此请谨慎使用以下命令(--dry-run):
rsync -avPr --ignore-existing --remove-source-files src/ dest
请注意尾部的/,因为这将递归到src而不是复制src本身,这应保留您现有的路径。
通过将--ignore-existing标志与--remove-source-files标志结合使用,您将仅删除src中已从src同步到dest的文件,即以前仅存在于dest中的文件。
要删除未同步的文件(即像src /中那样已经存在于dest /中的文件),可以使用:
for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done
要么
find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;
如果文件名可以包含空格/换行符/ ...关于Gilles关于特殊字符的注释,这当然是要注意的,并且有很多解决方案,最简单的方法是将-i传递给rm,它将在所有删除操作之前提示。如果提供了src /或其父路径来查找,那么完全限定的路径应导致diff和rm命令都正确处理所有文件名而不加引号。
for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done
您可以跳过|| echo $file
它,以确保完整性)
\?*[
,初始-
)。您需要在变量替换周围使用双引号,--
在文件名之前传递给实用程序,使用find … -exec …
而不是解析的输出find
。rm
混合使用命令,这是灾难的根源。
统一是您要寻找的工具。如果您更喜欢gui,请尝试unison-gtk。但是我认为它不会删除类似的文件:统一尝试使两个目录相同。但是,它将很容易1)识别要复制的文件;2)哪些需要手动合并。
以下脚本应该合理地执行操作。它将文件从源移动到目标,从不覆盖文件并根据需要创建目录。目的地中具有相应不同文件的源文件以及非常规文件或目录(例如,符号链接)的文件都将被保留。源中剩余的文件是存在冲突的文件。当心,我根本没有测试过。
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
' {} \;
另一种方法是在一个目录上进行联合安装,例如使用funionfs或unionfs-fuse。