这是一些代码记录

  • 这次是帮朋友恢复硬盘,扫描到的结果包含了好多个分区,通过将分区中的数据导出发现很多文件是重复的。所以想到通过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库来实现进度条的效果,感觉效果很好,只是这样的话,就不能随意输出东西了。否则会出现多个进度条,这个目前我不知道怎么解决问题,但是考虑到控制台输出东西会严重拖慢程序的运行速度,不输出也没什么关系。

[Python] 通过md5去重 筛选文件代码的更多相关文章

  1. [转] 三种Python下载url并保存文件的代码

    原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib ...

  2. 通过MD5排除重复文件

    今天下载了好多美女图片壁纸,可是看了一下发现好多图片重复了,有强迫症的我必须把重复的都给剔除掉,首先想到的当然是百度了,问问度娘有没有什么图片去重的工具,搜了一下还真有.奈何本人智商捉急用不来这高级的 ...

  3. Python实现删除目录下相同文件

    让我们来分析一下这个问题:首先,文件个数非常多,手工查找是不现实的,再说,单凭我们肉眼,在几千张图片或文件里面找到完全相同的难度也是很大的.所以要用程序实现.那么用程序怎么实现呢?根据什么判断两个文件 ...

  4. python解析VOC的xml文件并转成自己需要的txt格式

    在进行神经网络训练的时候,自己标注的数据集往往会有数据量不够大以及代表性不强等问题,因此我们会采用开源数据集作为训练,开源数据集往往具有特定的格式,如果我们想将开源数据集为我们所用的话,就需要对其格式 ...

  5. python中OS模块操作文件和目录

    在python中执行和操作目录和文件的操作是通过内置的python OS模块封装的函数实现的. 首先导入模块,并查看操作系统的类型: >>> import os os.name # ...

  6. hashlib —— Python 的 md5 和 sha1 加密

    python的md5和sha1加密 0. md5 与 sha1 MD5 的全称是 Message-Digest Algorithm 5(信息-摘要算法).128 位长度.目前 MD5 是一种不可逆算法 ...

  7. 记录我的 python 学习历程-Day06 is id == / 代码块 / 集合 / 深浅拷贝

    一.is == id 用法 在Python中,id是内存地址, 你只要创建一个数据(对象)那么就会在内存中开辟一个空间,将这个数据临时加载到内存中,这个空间有一个唯一标识,就好比是身份证号,标识这个空 ...

  8. 办公室文员必备python神器,将PDF文件表格转换成excel表格!

    [阅读全文] 第三方库说明 # PDF读取第三方库 import pdfplumber # DataFrame 数据结果处理 import pandas as pd 初始化DataFrame数据对象 ...

  9. (Python )格式化输出、文件操作、json

    本节学习Python的格式化输出,文件操作以及json的简单用法 1.格式化输出 将非字符串类型转换成字符串,可以使用函数:str() 或者repr() ,(这两个函数的区别目前我还没搞懂,求解答) ...

  10. lib/sqlalchemy/cextension/processors.c:10:20: 致命错误: Python.h:没有那个文件或目录

    本文地址:http://www.cnblogs.com/yhLinux/p/4063444.html $ sudo easy_install sqlalchemy [sudo] password fo ...

随机推荐

  1. es6数组方法find()、findIndex() filter()的总结

    find()查找符合条件数组的元素(只能够找出第一个符合条件的) // 查找出大33的元素. // find查找第一个符合条件的数组元素(只查找出第一个 找不到返回undefined) // 它的参数 ...

  2. vim 从嫌弃到依赖(17)——查找模式

    最开始介绍vim的时候,提到vim有普通模式.插入模式.可视模式和命令行模式,并且已经对这几个模式做了详细的介绍了.除了这几个模式以外,vim还有一个非常强大的模式--查找模式,为什么最开始没有将其列 ...

  3. TienChin-课程管理-创建工程

    创建方式与之前一样,如下奉上 generateCourse 代码. @Test void generateCourse() { String path = "E:\\Desktop\\Tie ...

  4. MySQL 常见面试题/知识点总结!(2021 最新版)| JavaGuide

    相关阅读: 2.7w字!Java基础面试题/知识点总结!(2021 最新版) 这篇文章之前发过,不过,我最近对其进行了重构完善并且修复了很多小问题.所以,在公号再同步一下! 内容很硬!强烈建议小伙伴们 ...

  5. .NET NativeAOT 指南

    .NET NativeAOT 指南 随着 .NET 8 的发布,一种新的"时尚"应用模型 NativeAOT 开始在各种真实世界的应用中广泛使用. 除了对 NativeAOT 工具 ...

  6. 最新版Emlog采集发布插件-免费下载

    推荐一款可以自动采集网页文章数据,并发布到Emlog网站的Emlog采集发布插件(兼容最新的Emlog Pro版本,也兼容之前的 Emlog 5.3 和 Emlog 6.0 版本),支持对接简数采集器 ...

  7. NC50614 取石子游戏 1

    题目链接 题目 题目描述 有一种有趣的游戏,玩法如下: 玩家:2人: 道具:N颗石子: 规则: 游戏双方轮流取石子:每人每次取走若干颗石子(最少取1颗,最多取K颗):石子取光,则游戏结束:最后取石子的 ...

  8. NC216012 Let'sPlayCurling

    题目链接 题目 题目描述 Curling is a sport in which players slide stones on a sheet of ice toward a target area ...

  9. NVME(学习笔记八)—Asymmetric Namespace Report

    8.20 非对称namespace访问报告 8.20.1 非对称namespace访问报告概况 非对称Namespace访问(ANA)在如下场景下产生,基于访问这个namespace的controll ...

  10. Vuex和普通全局对象

    Vuex中的核心方法 Vuex是一个专为Vue.js应用程序开发的状态管理模式,其采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.每一个Vuex应用的核心就是 ...