linux 合并文件夹:rsync?

linux 合并文件夹:rsync?

我有一个文件夹的两个副本

src/
dest/

我想合并它们,执行以下操作:

如果文件仅在src,我希望将其移动到dest

如果某个文件仅在中dest,我希望 IE 忽略它。

如果文件同时在具有相同的内容(即相同的大小和日期),从中删除src

如果文件同时在并且不是具有相同的内容,保留下来,src以便我可以手动合并它们。

只有极少数文件(占总文件的 0%到 5% 之间)应该属于最后一个类别,但我不知道如何区分两者中的和两者中的相同但不同的。

我曾尝试弄清​​楚如何做到这一点,rsync但至今无果。

答案1

我只进行了有限的功能测试,因此请小心使用此命令(--dry-run):

rsync -avPr --ignore-existing --remove-source-files src/ dest

请注意尾随的 /,因为这将递归到 src 而不是复制 src 本身,这应该保留您现有的路径。

通过将 --ignore-existing 标志与 --remove-source-files 标志结合使用,您将仅删除从 src 同步到 dest 的 src 文件,即以前不存在于 dest 中的文件。

要删除未同步的文件(即 dest/ 中已经存在的文件,如 src/ 中的文件),您可以使用:

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/ 或其父路径以供 find,则完全限定路径应该会导致 diff 和 rm 命令正确处理所有文件名,而无需引用。

答案2

齐奏就是您要找的工具。如果您更喜欢 gui,请尝试 unison-gtk。但我认为它不会删除类似的文件:unison 尝试让两个目录相同。尽管如此,它还是可以轻松 1) 识别要复制哪些文件;2) 哪些文件需要手动合并。

答案3

以下脚本应该可以合理地执行操作。它将文件从源移动到目标,从不覆盖文件并根据需要创建目录。在目标中具有相应不同文件的源文件将保持不变,非常规文件或目录(例如符号链接)的文件也是如此。源中剩余的文件是存在冲突的文件。请注意,我根本没有测试过它。

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
  ' {} \;

另一种方法是联合山一个目录在另一个目录之上,例如函数或者unionfs-fuse

相关内容