教你用Python尋找重復(fù)文件并刪除的腳本寫法
在實(shí)際生活中,經(jīng)常會(huì)有文件重復(fù)的困擾,即同一個(gè)文件可能既在A目錄中,又在B目錄中,更可惡的是,即便是同一個(gè)文件,文件名可能還不一樣。在文件較少的情況下,該類情況還比較容易處理,最不濟(jì)就是one by one的人工比較——即便如此,也很難保證你的眼神足夠犀利。倘若文件很多,這豈不是個(gè)impossible mission?最近在看《Python UNIX和Linux系統(tǒng)管理指南》,里面就有有關(guān)“數(shù)據(jù)比較”的內(nèi)容,在其基礎(chǔ)上,結(jié)合實(shí)際整理如下。
該腳本主要包括以下模塊:diskwalk,chechsum,find_dupes,delete。其中diskwalk模塊是遍歷文件的,給定路徑,遍歷輸出該路徑下的所有文件。chechsum模塊是求文件的md5值。find_dupes導(dǎo)入了diskwalk和chechsum模塊,根據(jù)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 file2.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函數(shù)返回了字典dup,該字典的鍵是重復(fù)的文件,值是原文件。這樣就解答了很多人的疑惑,畢竟,你怎么確保你輸出的是重復(fù)的文件呢?
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類構(gòu)造了3個(gè)函數(shù),實(shí)現(xiàn)的都是文件刪除功能、其中delete函數(shù)是直接刪除文件,dryrun函數(shù)是試運(yùn)行,文件并沒有刪除,interactive函數(shù)是交互模式,讓用戶來確定是否刪除。這充分了考慮了客戶的需求。
總結(jié):這四個(gè)模塊已封裝好,均可單獨(dú)使用實(shí)現(xiàn)各自的功能。組合起來就可批量刪除重復(fù)文件,只需輸入一個(gè)路徑。
最后,貼個(gè)完整版本的,兼容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()其中,第一個(gè)參數(shù)是待檢測(cè)的目錄。
到此這篇關(guān)于如何用Python尋找重復(fù)文件并刪除的文章就介紹到這了,更多相關(guān)Python刪除重復(fù)文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一篇文章帶你深入學(xué)習(xí)Python函數(shù)
這篇文章主要帶大家深入學(xué)習(xí)Python函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
Python實(shí)現(xiàn)中一次讀取多個(gè)值的方法
下面小編就為大家分享一篇Python實(shí)現(xiàn)中一次讀取多個(gè)值的方法,具有很好的參考價(jià)值,我對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04
50行Python代碼獲取高考志愿信息的實(shí)現(xiàn)方法
這篇文章主要介紹了50行Python代碼獲取高考志愿信息的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
Python中數(shù)組,列表:冒號(hào)的靈活用法介紹(np數(shù)組,列表倒序)
下面小編就為大家分享一篇Python中數(shù)組,列表:冒號(hào)的靈活用法介紹(np數(shù)組,列表倒序),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04
python重試裝飾器的簡(jiǎn)單實(shí)現(xiàn)方法
今天小編就為大家分享一篇python重試裝飾器的簡(jiǎn)單實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01
Python調(diào)用scp向服務(wù)器上傳文件示例
今天小編就為大家分享一篇Python調(diào)用scp向服務(wù)器上傳文件示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12

