比较2个目录并在第3个目录中复制差异


32

运行ubuntu 12.04,我想比较2个目录,例如folder1 /和folder2 /,并复制与folder3 /不同的任何文件。也有嵌套文件,因此也应复制匹配的子目录

有没有一个命令对我有帮助?我可以获得正在运行的已更改文件的完整列表:

rsync -rcnC --out-format="%f" folder1/ folder2/

但是rsync似乎无法将这些文件“导出”到另一个目标目录中。我可以将列表通过管道传输到cp或其他程序,以便在创建目录的同时复制文件吗?例如,我尝试

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

但这也不会保留目录,它只会复制folder3 /中的所有文件


我可能会使用的一些组合diff -qr,并awk建立列表,然后rsync...
ewwhite

我将如何在列表中使用rsync?
periklis

我要么运行一个for循环,要么使用该rsync --include-from=FILE选项。
ewwhite

(不要偷懒...)但是下面的rsync解决方案很优雅。
ewwhite

Answers:


38

使用--compare-dest。

从手册页:

--compare-dest = DIR-此选项指示rsync将目标计算机上的DIR用作附加层次结构,以比较目标文件与进行传输的情况(如果目标目录中缺少文件)。如果在DIR中找到与发件人文件相同的文件,则该文件将不会传输到目标目录。这对于仅创建较早备份已更改的文件的稀疏备份很有用。

首先使用--dry-run检查语法

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

然后,一旦您对输出感到满意:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

链接很好地解释了--compest-dest范围。


1
谢谢您,我不了解此参数的手册页说明。对于任何感兴趣的人,我都是这样做的rsync -rcC --compare-dest=folder2/ folder1/ folder3/
periklis

OsX用户快速注释。我rsync version 3.1.1 protocol version 31在我的本地计算机上,rsync无法理解参数的~/路径--compare-dest
Jevgeni Smirnov 2014年

4
对我来说,--compare-dest需要一条绝对的道路。
palswim 2015年

使用作者或OP的选项对我都不起作用。即,它输出fonts/Makefile.in文件,在文件folder2folder1目录中都相同。
Hi-Angel

3

这个小脚本应该可以工作:

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in `rsync -rcnC --out-format="%n"  $folder1 $folder2`
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

但是我也认为,解析diff -qr的输出将是一个更好的解决方案,因为它为您提供一致的每个文件的路径和名称。

编辑

这将是一个命令,您的命令略有修改。但是它将folder1在之下创建folder3。而且它不适用于完整路径,但是上面的脚本也不适用于完整路径。

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

我曾经\"rsync使其与包含空格的文件和目录。在Ubuntu 10.04上测试。希望能帮助到你。


谢谢,我希望有一个单一的命令
periklis

2
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

如果您愿意folder1在发出命令之前先进入,这就是我能想到的最简单的形式。

这是较慢的选项,但我相信它可以满足您的要求,并且可以使用非相对目录名称来执行:

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

我离开了你原来的 rsync命令,因为您说它给了您正确的文件列表(而且我的测试文件显然与您的不同,所以如果我搞砸了,我不能肯定地说我会得到正确的文件列表)用它)。

使用grep可以从中删除目录名称rsync

grep然后rsync使用的输出通过管道传递给另一个xargs。在参数中folder1/./{},多余的./内容用于告诉rsync创建以开头的相对目录./{},忽略folder1/。换句话说,它避免创建folder3/folder1/

我只能在CentOS 6.4上进行测试,但是AFAIK在Ubuntu 12.04中应该可以正常工作。

编辑: 我应该注意,史密斯安的答案无疑更好,但是我想用原始rsync命令巧妙地处理它,因为它可以为您提供所需的输出。

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.