linux合并文件夹:rsync?


13

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

src/
dest/

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

如果只有一个文件src,我希望将其移动到dest

如果文件仅在中dest,我希望它忽略IE单独留下的内容。

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

如果文件是在这两个并执行具有相同的内容,留下src这样我就可以手动将它们合并。

最后一个类别中应该只有很少的文件(占总文件的0%至5%),但我不知道如何将两者中的和两者分开,但是有所不同。

我试图弄清楚该怎么做,rsync但到目前为止没有任何结果。

Answers:


17

我仅执行了有限的功能测试,因此请谨慎使用以下命令(--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命令都正确处理所有文件名而不加引号。


更正:如果dest中已经存在相同的副本,则该命令不会从src中删除文件
Tok 2010年

是啊:(这是我发现很难搞清楚的部分。
大卫·奥尼尔

2
好吧,好消息是您可以无忧无虑地独立解决它:(如果需要,for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done您可以跳过|| echo $file它,以确保完整性)
Tok Tok

漂亮:那就是我所需要的。将其编辑为您的答案,我会接受的!
大卫·奥尼尔

@Tok:您的命令会窒息包含特殊字符(空格,文件名\?*[,初始-)。您需要在变量替换周围使用双引号--在文件名之前传递给实用程序,使用find … -exec …而不是解析的输出findrm混合使用命令,这是灾难的根源。
吉尔(Gilles)'所以

6

统一是您要寻找的工具。如果您更喜欢gui,请尝试unison-gtk。但是我认为它不会删除类似的文件:统一尝试使两个目录相同。但是,它将很容易1)识别要复制的文件;2)哪些需要手动合并。


它并不能完全满足OP的要求,但听起来可以完成OP的最终目标。+1
瑞安·汤普森

+1遗憾的是,我在其上运行该服务器的服务器没有安装统一功能,也没有安装它的权限。但这可能是对其他人的一个很好的答案。
大卫·奥尼尔

1
您可以从seas.upenn.edu/~bcpierce/unison//download/…下载统一可执行文件。将它安装在主目录中的某个位置,它只是一个文件。
JooMing 2010年

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

另一种方法是在一个目录上进行联合安装,例如使用funionfsunionfs-fuse

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.