[Python] 通过md5去重 筛选文件代码

世上唯一不能复制的是时间,唯一不能重演的是人生,唯一不劳而获的是年龄。该怎么走,过什么样的生活,全凭自己的选择和努力。人生很贵,请别浪费!与智者为伍,与良善者同行。[Python] 通过md5去重 筛选文件代码,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

这是一些代码记录

  • 这次是帮朋友恢复硬盘,扫描到的结果包含了好多个分区,通过将分区中的数据导出发现很多文件是重复的。所以想到通过python代码去重。
  • 首先把所有分区的图片文件都放到一个文件夹A中,如果命名有冲突,对于win10可以选”让我决定每个文件”然后把两个对勾都打上,这样对于重复的文件win10会给加上(1)这样的后缀(所以去重是把文件名比较长的移除)。通过下面的去重代码就能轻易移除掉重复的文件。
  • 因为朋友的硬盘上放了很多新的图片,所以通过第二个代码把A文件夹中存在于硬盘中的文件移除。
  • 然后,写完第二个代码之后想到了更好的思路以及进度条的实现,所以又写了一个验证的代码。

去重

通过获取md5去重,保留文件名比较短的版本(主要是去除命名中最后的(1)这样的标记) 为了保险起见 只是把重复的文件移动走了 而不是删除,代码出现错误也不至于有什么损失。强烈建议这么做

import os
import hashlib
import shutil

hash_dict = {}

def get_md5(file_name):
    with open(file_name, "rb") as f:
        r = f.read()
        m = hashlib.md5()
        m.update(r)
        return m.hexdigest()

A_file_list = os.listdir("A")

t_num = len(A_file_list)
print ("总文件数: " + str(t_num));
cnt = 0
for file in A_file_list:
    md5_str = get_md5('A/'+file)
    if md5_str in hash_dict:  # 重复文件
        print (f"重复: {hash_dict[md5_str]} | {file}");
        if len(file) < len(hash_dict[md5_str]):
            shutil.move('A/' + hash_dict[md5_str], 'B/' + hash_dict[md5_str])
            # os.remove('A/' + hash_dict[md5_str])
            hash_dict[md5_str] = file
        else:
            shutil.move('A/' + file, 'B/' + file)
            # os.remove('A/' + file)
    else:
        hash_dict[md5_str] = file
    cnt += 1
    print (f"{str(cnt)}/{str(t_num)}")

print ("done.")

递归查找文件比对筛选

通过上一步去重,下面的代码先对A文件夹中的文件都取md5,然后遍历F盘的文件,并且计算md5,如果有相同的,那么移动到B文件夹。

import os
import hashlib
import shutil

hash_dict = {}
f_file_cnt = 0

def get_md5(file_name):
    with open(file_name, "rb") as f:
        r = f.read()
        m = hashlib.md5()
        m.update(r)
        return m.hexdigest()
        
def fun(path):
    global f_file_cnt
    try:
        os.chdir(path)
    except:
        return
    file_list = os.listdir()
    for file in file_list:
        if os.path.isdir(file):
            fun(file)
        elif os.path.isfile(file):
            if os.path.getsize(file) > 73056832:
                continue
            md5_str = get_md5(file)
            # with open("D://F.md5", 'a') as f:
                # f.write(md5_str+"\n")
            if md5_str in hash_dict:
                try:
                    shutil.move("D://恢复/A/"+hash_dict[md5_str], "D://恢复/B/"+hash_dict[md5_str])
                    print ("D://恢复/A/"+hash_dict[md5_str])
                except Exception as e:
                    print(e)
            f_file_cnt += 1
            if (f_file_cnt % 50) == 0:
                print(f"{(f_file_cnt/25524)*100}% - {md5_str}")

    os.chdir("..")

A_file_list = os.listdir("A")

t_num = len(A_file_list)

print ("总文件数: " + str(t_num));

cnt = 0

#读取A文件夹的md5 与F盘现有文件对比 结果作为依据删除掉A文件夹的文件
print("载入A文件夹md5")
for file in A_file_list:
    md5_str = get_md5('A/'+file)
    hash_dict[md5_str] = file
    cnt += 1
    if (cnt % 50) == 0:
        print (f"{(cnt/t_num)*100}%")
print("A文件夹md5读取完毕\n开始遍历F盘")


fun("F:/")

print (f_file_cnt)
print ("done.")

最终检查

通过修改上面代码(参考注释的代码),可以先遍历一遍F盘的文件,得到文件的md5列表,然后再和A文件夹里面的文件按照下面的代码比对,能节省很多时间。原因是因为移动硬盘速度太慢了,我要是早点这么干,早就筛选出必要的文件了。。。

import os
import hashlib
import shutil
from tqdm import tqdm

f_hash_list = []

def get_md5(file_name):
    with open(file_name, "rb") as f:
        r = f.read()
        m = hashlib.md5()
        m.update(r)
        return m.hexdigest()
        

with open("D://F.md5") as f:
    f_hash_list = f.readlines()
    
file_list = os.listdir("B")

pbar = tqdm(total=len(file_list))

for file in file_list:
    md5_str = get_md5("B/"+file)
    if md5_str+"\n" in f_hash_list:
        try:
            shutil.move("B/"+file, "C/"+file)
        except Exception as e:
            print (e)
    pbar.update(1)

pbar.close()
print("done.")

这里也用到了tqdm库来实现进度条的效果,感觉效果很好,只是这样的话,就不能随意输出东西了。否则会出现多个进度条,这个目前我不知道怎么解决问题,但是考虑到控制台输出东西会严重拖慢程序的运行速度,不输出也没什么关系。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/225558.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!