比较不同结构的目录中的文件并显示差异(20.04)

比较不同结构的目录中的文件并显示差异(20.04)

虽然这听起来像是一项可以通过诸如此类的方式完成的任务rsyncdiff但我却未能成功。

据我所知,这些工具在比​​较文件时会考虑目录结构。

因此,如果“文件 A”位于~/Dir-A而“文件 B”位于~/Dir-B/Dir-BB,则它们将被检测为不同的文件,即使它们具有相同的哈希值。

要求/详细信息如下:

  • Ubuntu 20.04
  • 比较Dir-ADir-B
  • 忽略文件的位置(目录结构)。换句话说,我只需要检查文件,而不管它们位于哪个子目录中(因此,在上面的例子中,文件应该被视为相等);
  • 指定哪些文件在Dir-A,哪些不在Dir-B(反之亦然,最好在不同的列表/结果中);
  • Dir-ADir-B结构非常不同。在某些特定情况下,Dir-A应该具有一切Dir-B,并且还有更多;
  • 奖励:如果可行的话,能够检查是否Dir-A拥有来自多个其他目录的所有内容就好了。

总结一下:我的具体情况涉及检查内容和结构非常不同的多个备份和副本。

在某些特定情况下,我需要将一个大文件夹(即完整备份)与其他较小的文件夹进行比较,以检查备份是否具有应有的所有内容。

非常感谢您的关注。

答案1

我真的不知道如何在没有脚本的情况下做到这一点,所以这里有一个简短的 Python 脚本来帮助你入门


import hashlib
import os

def get_md5_file(filename, chunk_size=10240):
    ''' Returns md5 sum of the given filename
    '''
    md5_hash = hashlib.md5()
    with open(filename, 'rb') as f:
        while True:
            data = f.read(chunk_size)
            if not data:
                break
            
            md5_hash.update(data)
            
    digest = md5_hash.hexdigest()
    return digest

#print(get_md5('Dir-A/file1.txt'))
#print(get_md5('Dir-B/Dir-B/file1-duplicate.txt'))

def get_md5_dir(root, result=None):
    ''' Returns a dictionary with the md5 sum of every filename in directory root
    '''    
    if result is None:
        result = dict()
    
    for root, dirs, files in os.walk(root):
        for filename in files:
            filename = os.path.join(root, filename)
            md5 = get_md5_file(filename)
            if md5 in result:
                print('Warning, duplicate md5 sum', result[md5], filename)
            
            result[md5] = filename
    
    return result

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='Compare directories by md5 sum')
    parser.add_argument('dirA', help='Specify first directory')
    parser.add_argument('dirB', help='Specify one or more directory to compare to',
                        nargs='+')
    args = parser.parse_args()

    # Get md5 sum for each file in dirA and each file in (possibly multiple) dirB
    md5_dirA = get_md5_dir(args.dirA)
    md5_dirB = dict()
    for root in args.dirB:
        get_md5_dir(root, md5_dirB) # update dict in place

    #print(md5_dirA)
    #print(md5_dirB)

    # print files in dirA, but not in dirB
    for md5 in md5_dirA:
        if md5 not in md5_dirB:
            print('%s (%s) not in dirB' % (md5_dirA[md5], md5))

    # print files in dirB, not in dirA
    for md5 in md5_dirB:
        if md5 not in md5_dirA:
            print('%s (%s) not in dirA' % (md5_dirB[md5], md5))
    

要使用,请将其保存为文本文件 compare_files_by_hash.py,然后python3 compare_files_by_hash.py Dir-A Dir-B

奖励:如果可行的话,最好能够检查 Dir-A 是否拥有来自多个其他目录的所有内容。

我不确定我是否理解了这一点,但上面允许多个 Dir-B 目录,即您可以这样做python3 compare_files_by_hash.py Dir-A Dir-B Dir-B-2 Dir-B-3,就好像Dir-B Dir-B-2 Dir-B-3都在一样Dir-B

相关内容