我是一名摄影师,做了很多备份。多年来,我发现自己拥有很多硬盘。现在我买了一台 NAS 并使用 rsync 在一个 3TB raid 1 上复制了我所有的照片。根据我的脚本,这些文件中有大约 1TB 是重复的。这来自于在我的笔记本电脑上删除文件之前进行多次备份并且非常混乱。我确实在旧硬盘上备份了所有这些文件,但如果我的脚本把事情搞砸了,那就太痛苦了。您能否看看我的重复查找器脚本并告诉我您是否认为我可以运行它?我在一个测试文件夹上尝试过,看起来还可以,但我不想在 NAS 上搞砸。
该脚本在三个文件中包含三个步骤。在第一部分中,我找到所有图像和元数据文件,并将它们放入搁置数据库(datenbank)中,并以它们的大小作为键。
import os
import shelve
datenbank = shelve.open(os.path.join(os.path.dirname(__file__),"shelve_step1"), flag='c', protocol=None, writeback=False)
#path_to_search = os.path.join(os.path.dirname(__file__),"test")
path_to_search = "/volume1/backup_2tb_wd/"
file_exts = ["xmp", "jpg", "JPG", "XMP", "cr2", "CR2", "PNG", "png", "tiff", "TIFF"]
walker = os.walk(path_to_search)
counter = 0
for dirpath, dirnames, filenames in walker:
if filenames:
for filename in filenames:
counter += 1
print str(counter)
for file_ext in file_exts:
if file_ext in filename:
filepath = os.path.join(dirpath, filename)
filesize = str(os.path.getsize(filepath))
if not filesize in datenbank:
datenbank[filesize] = []
tmp = datenbank[filesize]
if filepath not in tmp:
tmp.append(filepath)
datenbank[filesize] = tmp
datenbank.sync()
print "done"
datenbank.close()
第二部分。现在我删除列表中只有一个文件的所有文件大小,并创建另一个搁置数据库,其中 md5 哈希作为键,文件列表作为值。
import os
import shelve
import hashlib
datenbank = shelve.open(os.path.join(os.path.dirname(__file__),"shelve_step1"), flag='c', protocol=None, writeback=False)
datenbank_step2 = shelve.open(os.path.join(os.path.dirname(__file__),"shelve_step2"), flag='c', protocol=None, writeback=False)
counter = 0
space = 0
def md5Checksum(filePath):
with open(filePath, 'rb') as fh:
m = hashlib.md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
for filesize in datenbank:
filepaths = datenbank[filesize]
filepath_count = len(filepaths)
if filepath_count > 1:
counter += filepath_count -1
space += (filepath_count -1) * int(filesize)
for filepath in filepaths:
print counter
checksum = md5Checksum(filepath)
if checksum not in datenbank_step2:
datenbank_step2[checksum] = []
temp = datenbank_step2[checksum]
if filepath not in temp:
temp.append(filepath)
datenbank_step2[checksum] = temp
print counter
print str(space)
datenbank_step2.sync()
datenbank_step2.close()
print "done"
最后是最危险的部分。对于 evrey md5 密钥,我检索文件列表并执行额外的 sha1。如果匹配,我会删除该列表中除第一个文件之外的每个文件,并创建一个硬链接来替换已删除的文件。
import os
import shelve
import hashlib
datenbank = shelve.open(os.path.join(os.path.dirname(__file__),"shelve_step2"), flag='c', protocol=None, writeback=False)
def sha1Checksum(filePath):
with open(filePath, 'rb') as fh:
m = hashlib.sha1()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
for hashvalue in datenbank:
switch = True
for path in datenbank[hashvalue]:
if switch:
original = path
original_checksum = sha1Checksum(path)
switch = False
else:
if sha1Checksum(path) == original_checksum:
os.unlink(path)
os.link(original, path)
print "delete: ", path
print "done"
你怎么看?非常感谢。
*如果这很重要:它是 Synology 713+ 并且具有 ext3 或 ext4 文件系统。