虽然这听起来像是一项可以通过诸如此类的方式完成的任务rsync
,diff
但我却未能成功。
据我所知,这些工具在比较文件时会考虑目录结构。
因此,如果“文件 A”位于~/Dir-A
而“文件 B”位于~/Dir-B/Dir-BB
,则它们将被检测为不同的文件,即使它们具有相同的哈希值。
要求/详细信息如下:
- Ubuntu 20.04
- 比较
Dir-A
和Dir-B
; - 忽略文件的位置(目录结构)。换句话说,我只需要检查文件,而不管它们位于哪个子目录中(因此,在上面的例子中,文件应该被视为相等);
- 指定哪些文件在
Dir-A
,哪些不在Dir-B
(反之亦然,最好在不同的列表/结果中); - 和
Dir-A
的Dir-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
。