教你用Python寻找重复文件并删除的脚本写法
作者:iVictor 发布时间:2023-08-21 19:33:43
在实际生活中,经常会有文件重复的困扰,即同一个文件可能既在A目录中,又在B目录中,更可恶的是,即便是同一个文件,文件名可能还不一样。在文件较少的情况下,该类情况还比较容易处理,最不济就是one by one的人工比较——即便如此,也很难保证你的眼神足够犀利。倘若文件很多,这岂不是个impossible mission?最近在看《Python UNIX和Linux系统管理指南》,里面就有有关“数据比较”的内容,在其基础上,结合实际整理如下。
该脚本主要包括以下模块:diskwalk,chechsum,find_dupes,delete。其中diskwalk模块是遍历文件的,给定路径,遍历输出该路径下的所有文件。chechsum模块是求文件的md5值。find_dupes导入了diskwalk和chechsum模块,根据md5的值来判断文件是否相同。delete是删除模块。具体如下:
1. diskwalk.py
import os,sys
class diskwalk(object):
def __init__(self,path):
self.path = path
def paths(self):
path=self.path
path_collection=[]
for dirpath,dirnames,filenames in os.walk(path):
for file in filenames:
fullpath=os.path.join(dirpath,file)
path_collection.append(fullpath)
return path_collection
if __name__ == '__main__':
for file in diskwalk(sys.argv[1]).paths():
print file
2.chechsum.py
import hashlib,sys
def create_checksum(path):
fp = open(path)
checksum = hashlib.md5()
while True:
buffer = fp.read(8192)
if not buffer:break
checksum.update(buffer)
fp.close()
checksum = checksum.digest()
return checksum
if __name__ == '__main__':
create_checksum(sys.argv[1])
3. find_dupes.py
from checksum import create_checksum
from diskwalk import diskwalk
from os.path import getsize
import sys
def findDupes(path):
record = {}
dup = {}
d = diskwalk(path)
files = d.paths()
for file in files:
compound_key = (getsize(file),create_checksum(file))
if compound_key in record:
dup[file] = record[compound_key]
else:
record[compound_key]=file
return dup
if __name__ == '__main__':
for file in findDupes(sys.argv[1]).items():
print "The duplicate file is %s" % file[0]
print "The original file is %s\n" % file[1]
findDupes函数返回了字典dup,该字典的键是重复的文件,值是原文件。这样就解答了很多人的疑惑,毕竟,你怎么确保你输出的是重复的文件呢?
4. delete.py
import os,sys
class deletefile(object):
def __init__(self,file):
self.file=file
def delete(self):
print "Deleting %s" % self.file
os.remove(self.file)
def dryrun(self):
print "Dry Run: %s [NOT DELETED]" % self.file
def interactive(self):
answer=raw_input("Do you really want to delete: %s [Y/N]" % self.file)
if answer.upper() == 'Y':
os.remove(self.file)
else:
print "Skiping: %s" % self.file
return
if __name__ == '__main__':
from find_dupes import findDupes
dup=findDupes(sys.argv[1])
for file in dup.iterkeys():
delete=deletefile(file)
#delete.dryrun()
delete.interactive()
#delete.delete()
deletefile类构造了3个函数,实现的都是文件删除功能、其中delete函数是直接删除文件,dryrun函数是试运行,文件并没有删除,interactive函数是交互模式,让用户来确定是否删除。这充分了考虑了客户的需求。
总结:这四个模块已封装好,均可单独使用实现各自的功能。组合起来就可批量删除重复文件,只需输入一个路径。
最后,贴个完整版本的,兼容Python 2.0, 3.0。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from __future__ import print_function
import os, sys, hashlib
class diskwalk(object):
def __init__(self, path):
self.path = path
def paths(self):
path = self.path
files_in_path = []
for dirpath, dirnames, filenames in os.walk(path):
for each_file in filenames:
fullpath = os.path.join(dirpath, each_file)
files_in_path.append(fullpath)
return files_in_path
def create_checksum(path):
fp = open(path,'rb')
checksum = hashlib.md5()
while True:
buffer = fp.read(8192)
if not buffer: break
checksum.update(buffer)
fp.close()
checksum = checksum.digest()
return checksum
def findDupes(path):
record = {}
dup = {}
d = diskwalk(path)
files = d.paths()
for each_file in files:
compound_key = (os.path.getsize(each_file), create_checksum(each_file))
if compound_key in record:
dup[each_file] = record[compound_key]
else:
record[compound_key] = each_file
return dup
class deletefile(object):
def __init__(self, file_name):
self.file_name = file_name
def delete(self):
print("Deleting %s" % self.file_name)
os.remove(self.file_name)
def dryrun(self):
print("Dry Run: %s [NOT DELETED]" % self.file_name)
def interactive(self):
try:
answer = raw_input("Do you really want to delete: %s [Y/N]" % self.file_name)
except NameError:
answer = input("Do you really want to delete: %s [Y/N]" % self.file_name)
if answer.upper() == 'Y':
os.remove(self.file_name)
else:
print("Skiping: %s" % self.file_name)
return
def main():
directory_to_check = sys.argv[1]
duplicate_file = findDupes(directory_to_check)
for each_file in duplicate_file:
delete = deletefile(each_file)
delete.interactive()
if __name__ == '__main__':
main()
其中,第一个参数是待检测的目录。
来源:https://www.cnblogs.com/ivictor/p/4377609.html
猜你喜欢
- 代码如下:declare @Q_ID uniqueidentifier set @Q_ID = dbo.uf_GetParamValueBy
- 装饰器本质是一个接受参数为函数的函数。作用:为一个已经实现的方法添加额外的通用功能,比如日志记录、运行计时等。举例1.不带参数的装饰器,不用
- 以SQL Server 2012 为例上图是部分数据库的截图, 我们执行DENY VIEW any DATABASE to PUBLIC;然
- 功能描述:1、右击节点可进行增删改2、可对节点数据进行模糊查询3、右击第一级节点可以进行同级节点增加4、双击节点或点击修改节点 都可以对节点
- Flask框架是Python开发的一个基于Werkzeug和Jinja 2的web开发微框架,它的优势就是极其简洁, 但又非常灵活,而且容易
- 忽然想起一个CSS的特性,写一段代码玩玩:<style type="text/css">body {font
- c#连接sqlserver、插入数据、从数据库获取时间using System;using System.Data.SqlClient;na
- 本文实例为大家分享了JavaScript制作验证码的具体代码,供大家参考,具体内容如下<html><head><
- 目录一、== 是比较两个对象的内容是否相等二、is 比较的是两个实例对象是不是完全相同三、使用is注意python对于小整数使用对象池存储问
- 如何在ADO服务器端利用好缓存技术?请看下面示例,这是一个用来显示图书分类的例子程序:displayBooks.asp< %
- 前言opencv中封装了一个专门用于求解cv::Mat均值的函数,即cv::mean(&cv::Mat),该函数会得到Mat中各个通
- Python中 join() 函数的使用函数:string.join()Python中有join()和os.path.join()两个函数,
- 之前写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统。blog系统很简单,只有一个页面,然后麻雀虽小五脏俱全。这里
- 牛顿摆是一个1960年代发明的桌面演示装置,五个质量相同的球体由吊绳固定,彼此紧密排列。又叫:牛顿摆球、动量守恒摆球、永动球、物理撞球、碰碰
- 对于每个程序开发者来说,调试几乎是必备技能。代码写到一半卡住了,不知道这个函数执行完的返回结果是怎样的?调试一下看看代码运行到一半报错了,什
- 1. glob文件名模式匹配尽管glob API很小,但这个模块的功能却很强大。只要程序需要查找文件系统中名字与某个模式匹配的一组文件,就可
- 修改密码://选择数据库use mysql;//修改密码update user set password=password('新密码
- 本文实例讲述了Python记录详细调用堆栈日志的方法。分享给大家供大家参考。具体实现方法如下:import sysimport osdef
- python发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是python自带的,只需import即可使用。smtplib
- 概述本文主要介绍一种降维方法,PCA(Principal Component Analysis,主成分分析)。降维致力于解决三类问题。1.