批量刪除同名電子書(保留指定格式)是一款Python批量刪除同名電子書籍工具助手,小書庫清理走起,陸陸續(xù)續(xù)存了上百G的電子書,很多電子書同一本卻有4種格式,epub,mobi,azw3, pdf,多浪費(fèi)硬盤啊,尋遍全網(wǎng),沒有現(xiàn)成的軟件,只能自己動(dòng)手了。把其它格式的全刪除了,留下epub格式的,慢慢欣賞就足夠。
軟件靈感:
昨晚和朋友聊微信,突然想起盤里的200多G電子書,有很多格式相同的,太占容量了,5萬多本,占了快200多G,手動(dòng)刪除了一些不感興趣的書籍。和朋友討論如果寫代碼來刪除一些同名但格式不同的電子書,處理流程應(yīng)該怎么樣。后來朋友突然說,其實(shí)用數(shù)據(jù)庫也可以弄,而且很快:
第一步:用bat批處理遍歷子目錄的文件路徑,我測試發(fā)現(xiàn),5萬多本的電子書,生成路徑文本不用3秒就完成了,4M大小的文本。
第二步:導(dǎo)到數(shù)據(jù)庫,分割出文件名,不帶后綴名那種 ,排序,加上編號,然后拼接上絕對路徑,再刪除指定編號的(刪除是為了保留同名的某一本電子書),剩下的就是同名且格式不同的電子書路徑了。
第三步:在數(shù)據(jù)庫上,給每行路徑前加del /F /S /Q 命令,導(dǎo)出為文本,改后綴為bat,運(yùn)行,即可把所有同名的電子書刪除。
然后我就想了一下,還寫啥程序,這用數(shù)據(jù)庫,一下就能完成的事,寫程序還要花一天時(shí)間,太傻了。。。然后因?yàn)椴欢當(dāng)?shù)據(jù)庫,昨晚是用excel對5萬多行的電子書進(jìn)行分列,拼接等等處理,不熟悉,一邊百度一邊弄的。。。。還是忙了2小時(shí),不懂?dāng)?shù)據(jù)庫真慘。。。
今天一早起來,覺得還是不爽,我的電子書是處理完了,廣大的吾友小書庫滿了怎么辦,不懂程序的吾友,清理又不方便,所以還是嗑嗑碰碰,絞盡腦汁花了一天,寫到現(xiàn)在發(fā)貼才寫完python小工具《批量刪除同名電子書 僅保留一本指定的格式》
使用說明:
第一步:雙擊運(yùn)行《python小工具-批量刪除同名電子保留指定格式》,默認(rèn)是按epub>mobi>azw3>pdf>doc>chm>html>txt 順序來保留電子書,簡單說,如果你電腦里不同的文件夾里同時(shí)存在著多種格式的同一個(gè)名字的電子書,且其中有一本格式是epub,那么程序會保留epub格式的,如果沒有epub,只有其它格式,程序會依上面的順序,依次判斷,最后,如果你的電子書格式在上面都沒有,例如是ppt格式的,程序會自動(dòng)保留一本,其它的一律刪除。之所以優(yōu)先保留epub,是因?yàn)槠鋲嚎s率相對mobi高點(diǎn),體積小點(diǎn),兩者排版差不多,以上關(guān)于epub和mobi的壓縮率大小是我百度的。
第二步:回車后,會彈出窗口,你選擇電子書所在的目錄就行,會遍歷子目錄,列舉出所有的電子書路徑,千萬不要選其它什么電腦軟件或者非電子書的目錄,免得把你電腦軟件的一些文件誤刪除。
第三步:選完電子書目錄后,靜心等待就行,稍等片刻,會輸出正在刪除xxx路徑電子書的字樣,當(dāng)有些電子書文件是只讀屬性, 會自動(dòng)調(diào)用cmd命令強(qiáng)制刪除。
第四步:當(dāng)刪除完畢后,會自動(dòng)打開電子書所在的目錄,到這一步,已經(jīng)是完成整理了哦,看看你的硬盤省了多少內(nèi)存(貌似是電子書是刪除到回收站了,測試時(shí)沒有留意,建議執(zhí)行完畢后,清理一次回收站,再看看硬盤省下多少容量)。
第五步:用下面我提供的 批量刪除空文件夾軟件,批量刪除空的電子書目錄。完美,哈哈。
注意事項(xiàng):打個(gè)比方,如果你想優(yōu)先保留azw3格式的電子書,不要其它格式的,那就修改源碼中的
[("azw3", "AZW3"),("epub", "EPUB"), ("mobi", "MOBI"),("pdf", "PDF"), ("doc", "DOC"),("chm", "CHM"), ("html", "HTML"),("txt",
列表里的元組順序。有編程底子的應(yīng)該懂,這是列表里嵌入了元組。如果不懂編程的,修改時(shí),要特別注意逗號大小寫這些。
送到嘴上吧:打包了多種優(yōu)先順序不一樣的exe,自行挑選使用那個(gè)
溫馨提示:
請先復(fù)制一些相同名字但不同格式的電子書,分別扔到幾個(gè)子目錄文件夾里,用我的軟件自行測試幾次,觀察使用后的結(jié)果是否和你預(yù)期的結(jié)果一致,再對自己的電子書庫大批量使用。免得誤刪了你的電子書了,豈不找我拼命。
批量刪除完同名電子書后,可能會有一些目錄是空的,此是就用它來批量清理空目錄
批量刪除空文件夾的使用教程:
記得勾上下面的兩個(gè)勾,否則不會刪除空的子目錄。
如果你想用數(shù)據(jù)庫或excel來批量刪除,可以下載下面這個(gè)批處理,提取絕對路徑:批處理 遍歷所有目錄及子目錄的文件路徑
軟件源碼:
from tkinter.filedialog import * #這個(gè)主要作用是os模塊 刪除文件,和運(yùn)行時(shí)彈出,讓你們選擇要?jiǎng)h除書籍的目錄。
from operator import itemgetter #這個(gè)模塊好像可以根據(jù)2個(gè)條件來排序,下面用來根據(jù) 書名和后綴名 排序.
from os import startfile
#下面可能有些功能或變量是多少余的,算法不精,時(shí)間來湊,只能用比較笨的方法來實(shí)現(xiàn)。
# 整體思路:
# 和上面的excel處理差不多,都是先列舉出電子書路徑,然后根據(jù)相同的書名對路徑排序,再剔除只有一本的書的路徑,剩下的就是重復(fù)的書本路徑了,然后再根據(jù)算法判斷,優(yōu)先剔除epub格#式的,其次是mobi,再到azw3,再到pdf,再到。。。。。。,如果指定的格式都沒有,就從重復(fù)的路徑列表中,去除第一個(gè)路徑,剩下的電子書路徑,都是重復(fù)的。最后,大膽的調(diào)用刪除命#令,全部刪刪刪刪刪刪,如果刪除出錯(cuò),就調(diào)用cmd命令強(qiáng)制刪除。
Files_Names={
"sort_list":[], #后面,這個(gè)元素列表,會存儲以下信息 [絕對路徑,電子書名,后綴名,同一本書的數(shù)量序號,是否重復(fù)]
"ml_name":""
}
def list_name(ml_name):
file_names = os.listdir(ml_name) # 根據(jù)選擇的目錄列出里面的文件及目錄 返回值為列表
if file_names != "": # 只要返回的文件路徑和目錄路徑不為空,防止你犯二,選擇了一個(gè)沒有文件的空目錄
for i in range(0, len(file_names)): # 列表轉(zhuǎn)換為循環(huán)數(shù)。
path = os.path.join(ml_name, file_names[i]) #電子書絕對路徑 例如:E://電子書/1文件夾/家書.epub
if os.path.isfile(path): # 如果為真,則是文件
# 實(shí)際測試,發(fā)現(xiàn)有一些電子書,沒有后綴名,故加上判斷,沒有.的大概率是沒有后綴名的書籍,此類的就放棄,不整理。之所以判斷.號是否存在于path[-6:]而不是判斷是否存在整個(gè)絕對路徑path中,是因?yàn)榘l(fā)現(xiàn)有些文件夾名帶有.號,而此時(shí)存在這個(gè)文件夾里的電子書恰巧是沒有后綴名的,這種情況就會造成誤判認(rèn)為其有后綴名。所以我才判斷.號是否存在于path[-6:],而不用整個(gè)路徑判斷
if "." in path[-6:]:
hj=path.split(".")[-1] #分割出電子書后綴名 例如epub
name_nohj=path.split("/")[-1].replace("." + hj, "") #分割,替換去除后綴名,只剩下電子書名 例如:家書
Files_Names["sort_list"].append([path, name_nohj, hj]) #[絕對路徑,電子書名,后綴名]
else: # 如果不是文件,那應(yīng)該是目錄,就加上/,再調(diào)用自身方法,進(jìn)行遞歸列出下一層的文件,聽說很多人在遞歸這里搞不明白。。。
try:
list_name(path + "/")
except:
print("訪問目錄出錯(cuò),可能不是一個(gè)目錄,或者是奇奇怪怪的文件名")
if __name__ == '__main__':
#format_hj變量用于 指定電子書優(yōu)先留下的格式,在前面的格式元組是要優(yōu)先留下的,因?yàn)閑pub相對mobi壓縮率高,排版差不多,所以優(yōu)先留下epub的,其次是mobi,再到azw3 .....最后到txt,如果你的電子書,都不屬于下面的格式,那就不管格式了,自動(dòng)留下第一本,其它重復(fù)的書就刪了。
#如果你們要優(yōu)先留下azw3格式的,只需要調(diào)一下 下面的元組順序就行,把("azw3", "AZW3")放到第一。
format_hj = [ ("pdf", "PDF"), ("azw3", "AZW3"), ("mobi", "MOBI"), ("epub", "EPUB"),("doc", "DOC"),("chm", "CHM"), ("html", "HTML"),("txt", "TXT")]
Files_Names["ml_name"]=askdirectory() #選擇電子書所在的目錄并存到變量里,后面重命名完成后,調(diào)用這個(gè)變量,顯示文件夾出來
if Files_Names["ml_name"]!="": #此判斷為了防止你不選擇文件夾,直接點(diǎn)了取消,此時(shí)返回空,就不執(zhí)行遍歷電子書功能。
Files_Names["ml_name"] += "/"
list_name(Files_Names["ml_name"]) # 把選擇的目錄傳入到list_name方法中,進(jìn)行遞歸遍歷照片文件路徑
aa=sorted(Files_Names["sort_list"], key=itemgetter(1,2)) #根據(jù) 書名和后綴名 排序,出來的效果就是 即使不同文件夾里,但名字相同的電子書,都會排在一起,方便后期用挑選需要的格式,和刪除
# 例如:
# ['E:/電子書合集/20200101/豆瓣高分電子書合集/酒神.azw3', '酒神', 'azw3']
# ['E:/電子書合集/20200101/酒神.epub', '酒神', 'epub']
# ['E:/電子書合集/電子書/小說/酒神.mobi', '酒神', 'mobi']
# 循環(huán)判斷,給電子書,加上數(shù)字序號,當(dāng)遇到重復(fù)的書本就加1,遇到不同的書本,就恢復(fù)序號為1
for index,i in enumerate(aa):
num=1
if index!=0:
if (i[1] == q_i[1]):
num=q_i[3]+1 #數(shù)字序號增加
q_i = i
i.append(num)
#根據(jù)上面的數(shù)字序號,循環(huán)判斷,是否重復(fù),重復(fù)的加上”重“字,不重復(fù)即只有一本的,加上”不“字
for index,i in enumerate(aa):
repeat = "不"
if index!=0:
if (i[3] == q_i[3]+1):
q_i.pop()
q_i.append("重")
repeat="重"
q_i = i
i.append(repeat)
#把在電子書列表中,有 不 字的列表 直接 用倒序刪除掉。 不能用順序,這是一個(gè)坑
for i in range(len(aa) - 1, -1, -1):
if "不" in aa[i][4]:
del aa[i]
#下面再通過把同一本書不同格式,合并到同一個(gè)列表中。再塞到一個(gè)大列表里。
bbb=[] #瞎雞亂定的變量名,當(dāng)時(shí)心態(tài)已經(jīng)崩了 小列表
ccc=[] #瞎雞亂定的變量名,當(dāng)時(shí)心態(tài)已經(jīng)崩了 大列表
for index, i in enumerate(aa):
if index!=0:
if (i[3] == q_i[3]+1): #這里通過判斷前一個(gè)和后一個(gè)的數(shù)量序號是否相等,判斷是否同一本書
bbb.append(i) #是同一本書,就塞到小列表中
else:
ccc.append(bbb) #表示不是同一本書,就把當(dāng)前的塞到大列表,結(jié)束,開始新的一輪加塞
bbb = [] #清空小列表
bbb.append(i) #往小列表加進(jìn)新的一本書
else:
bbb.append(i) #第一本書,就塞到小列表中
q_i = i
ccc.append(bbb) #最后一本 塞進(jìn)大列表
if len(ccc[0])!=0:
for i in ccc: #根據(jù)算法,刪除需要的格式,留下不需要的格式電子書,后面就根據(jù)這些不需要的電子書絕對路徑,循環(huán)刪除。
for hj in format_hj: #這是要保留的格式
BOOL = False
for index,o in enumerate(i): #這里的i表示同一本書,但不同格式的列表,o表示具體的一本書的路徑信息列表
if hj[0] in o[2] or hj[1] in o[2]:
i.pop(index)
BOOL=True
break
if BOOL:
break
if BOOL==False: #如果多本書名相同的電子書格式都不符合 format_hj指定的格式,就按順序移除第一本,即保留第一本。
i.pop(0)
for i in ccc:
for o in i:
try:
os.remove(o[0])
print("刪除:%s"%o[0])
except:
print("刪除不了,將調(diào)用cmd命令刪除!"+o[0])
o[0]=o[0].replace("/","\\") #不替換一下反斜杠,命令不生效
cmdd="del /F /S /Q "+o[0]
os.system(cmdd)
else:
print("竟然沒有重名的書籍!恭喜!恭喜!恭喜!恭喜!恭喜!恭喜!")
startfile(Files_Names["ml_name"]) # 完成后自動(dòng)打開 壓縮圖片所在的文件夾