如何比较两个文件夹并将差异复制到第三个文件夹?

Tha*_*ane 23 diff rsync file-copy files

你有三个文件夹:

  • 文件夹current,其中包含您当前的文件
  • 文件夹old,其中包含相同文件的旧版本
  • 文件夹差异,它只是一个空文件夹

你如何比较当前和副本是不同的(或全新的)中的文件当前区别


我四处搜索,这似乎是一件很容易解决的事情,但我无法在我的特定示例中使用它。大多数消息来源建议使用rsync,所以我最终使用了以下命令:

rsync -ac --compare-dest=../old/ new/ difference/
Run Code Online (Sandbox Code Playgroud)

然而,这样做是将所有文件从new复制到difference,即使是那些与old相同的文件。

如果它有帮助(也许命令没问题,而故障出在其他地方),我就是这样测试的:

  1. 我做了三个文件夹。
  2. 我在旧的.
  3. 我将文件从old复制到new
  4. 我在new 中更改了一些文件的内容并添加了一些其他文件。
  5. 我运行了上面的命令并检查了差异的结果。

过去几天我一直在寻找解决方案,我真的很感激一些帮助。它不一定必须使用 rsync,但如果可能的话,我想知道我做错了什么。

Tha*_*ane 22

我已经弄清楚了我的问题是什么:

我比较的文件有不同的时间戳。我不应该使用-a参数,我假设是因为 rsync 在复制文件时试图保留时间戳。对我有用的命令是:

rsync -rvcm --compare-dest=../old/ new/ difference/
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,这个答案应该是可以接受的,因为它要简单得多。此外,该命令仅在我为 `old/` 和 `new/` 提供完整路径时才对我有用。 (2认同)
  • 需要注意的是,compare-dest 必须是从实际 dest 内部看到的差异的相对路径 (2认同)

小智 7

我不确定您是否可以使用任何现有的 linux 命令(例如 rsync 或 diff)来执行此操作。但就我而言,我必须使用 Python 编写自己的脚本,因为 Python 具有用于文件比较的“filecmp”模块。我已经在我的个人网站上发布了整个脚本和用法 - http://linuxfreelancer.com/

它的用法很简单——按顺序给它新目录、旧目录和差异目录的绝对路径。

#!/usr/bin/env python

import os, sys
import filecmp
import re
from distutils import dir_util
import shutil

holderlist = []


def compareme(dir1, dir2):
    dircomp = filecmp.dircmp(dir1, dir2)
    only_in_one = dircomp.left_only
    diff_in_one = dircomp.diff_files
    dirpath = os.path.abspath(dir1)
    [holderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in only_in_one]
    [holderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compareme(
                os.path.abspath(os.path.join(dir1, item)),
                os.path.abspath(os.path.join(dir2, item)),
            )
        return holderlist


def main():
    if len(sys.argv) > 3:
        dir1 = sys.argv[1]
        dir2 = sys.argv[2]
        dir3 = sys.argv[3]
    else:
        print "Usage: ", sys.argv[0], "currentdir olddir difference"
        sys.exit(1)

    if not dir3.endswith("/"):
        dir3 = dir3 + "/"

    source_files = compareme(dir1, dir2)
    dir1 = os.path.abspath(dir1)
    dir3 = os.path.abspath(dir3)
    destination_files = []
    new_dirs_create = []
    for item in source_files:
        destination_files.append(re.sub(dir1, dir3, item))
    for item in destination_files:
        new_dirs_create.append(os.path.split(item)[0])
    for mydir in set(new_dirs_create):
        if not os.path.exists(mydir):
            os.makedirs(mydir)
    # copy pair
    copy_pair = zip(source_files, destination_files)
    for item in copy_pair:
        if os.path.isfile(item[0]):
            shutil.copyfile(item[0], item[1])


if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)