首页 > 其他分享 >更新:删除指定文件夹下所有重复文件

更新:删除指定文件夹下所有重复文件

时间:2022-11-05 21:45:31浏览次数:43  
标签:文件 删除 重复 文件夹 file print path os md5

#!/usr/bin/python3.9
# 2022-11-05 还可优化 代码有冗余

import os
import hashlib
import time
import sys


def choiceWhat():
	"""
	# 选择功能 
	# 1 手动输入路径
	# 2 读取批量文本
	# 3 退出
	"""	
	while True:
		print("\n=============主菜单=============\n"
			"脚本功能:删除指定文件夹下所有重复文件\n"
			"版本:v0.1 [2022/11/05]\n"
			"请选择:\n"
			"1. 手动输入路径\n"
			"2. 读取批量文本\n"
			"3. 显示说明文本\n"
			"0. 再见\n")
		choices = input("请输入对应数字:")
		if choices == "1":
			# 手动一次只能删除一个文件夹里的重复文件
			delete_One()
		elif choices == "2":
			# 批处理
			delete_Many()
		elif choices == "3":
			# 帮助
			show_help()
		elif choices == "0":
			print("退出")
			sys.exit()
			# return
		else:
			print("只接受数字[0 1 2 3]")
			

# 手动输入路径删除
def delete_One():
	# 获取文件夹路径
	path = input("path:")
	# 判断是否为绝对路径并判断路径所指向的位置是否存在

	if not os.path.exists(path):
		print(f"错误:路径或文件不存在,返回主菜单\n")
		return

	if not os.path.isabs(path):
		print(f"错误:必须为绝对路径,返回主菜单\n")
		return

    # 存放文件的 md5 码
	all_md5 = {}  # 改为字典
	total_file = 0
	total_delete = 0
	# 开始时间
	start = time.time()
    # 遍历文件夹下的所有文件
	for file in os.listdir(path):
		# 文件数量加 1
		total_file += 1
		# 文件的路径
		real_path = os.path.join(path, file)
		# 判断文件是否是文件
		if os.path.isfile(real_path) == True:
			# 获取文件的md5码
			filemd5 = getmd5(real_path)
			# 如果文件 md5 已存在,则删除此文件
			if filemd5 in all_md5.keys():  # 字典的键为文件 md5 码
				total_delete += 1
				print(f"删除:{file}")
				os.remove(real_path)
				#os.remove(path +"/" + file)  windows下这种也可以用
			else:
				# 如果文件 md5 不存在,则将此文件的 md5 码添加到 all_md5 字典中
				all_md5[filemd5] = ""
	# 结束时间
	end = time.time()
	time_last = end - start
	print('文件总数:', total_file)
	print('删除个数:', total_delete)
	print('耗时:', time_last, '秒')
	print('任务完成')
	return

# 读取批量处理文件
def delete_Many():
	# 存放文件的 md5 码
	all_md5 = {}  # 改为字典
	total_file = 0
	total_delete = 0
	# 开始时间
	start = time.time()
	# 获取批处理文件所在路径
	path = input("path:")
	# 判断批处理文件否存在
	if not os.path.exists(path):
		print(f"错误:批处理文件不存在,返回主菜单\n")
		return
	else:
		print(f"\n检查中...\n检查结果:批处理文件'{path}'存在")
	# 新建一个空列表
	get_list = []
	file1 = open(path, 'r', encoding='utf-8') # 要去掉空行的文件 
	try:
		for line in file1.readlines():
			line = line.strip("\n")
			if line == '\n':
				line = line.strip("\n")
			if len(line) != 0:
				get_list.append(line)
	finally:
		file1.close()
	print("\n===批处理文件内容显示开始===")
	for s in get_list:
		print(s)
	print("===批处理文件内容显示结束===\n现在进行下一步\n")

	# i为列表长度 长度为0代表批处理文件内容有问题,返回主菜单
	i = len(get_list)
	if i == 0:
		print("批处理文件内容为空")
		return

	# 第一行格式不对就不处理 防止删错了
	if get_list[0] != "#filelist":
		print("为防误删除,请将批处理文件第一行内容修改为:\n#filelist\n")
		return

	for list1 in get_list:
		# 只要不是声明内容 就开始干活处理
		if list1 != "#filelist":
			# 一行一行处理
			path = list1
			# 判断是否为绝对路径并判断路径所指向的位置是否存在

			if not os.path.exists(path):
				print(f"错误:路径或文件不存在,返回主菜单\n")
				return

			if not os.path.isabs(path):
				print(f"错误:必须为绝对路径,返回主菜单\n")
				return

			# 显示一下处理哪个路径
			print(f"\n开始处理:{path}")

		    # 存放文件的 md5 码
			all_md5 = {}  # 改为字典
			total_file = 0
			total_delete = 0
			# 开始时间
			start = time.time()
		    # 遍历文件夹下的所有文件
			for file in os.listdir(path):
				# 文件数量加 1
				total_file += 1
				# 文件的路径
				real_path = os.path.join(path, file)
				# 判断文件是否是文件
				if os.path.isfile(real_path) == True:
					# 获取文件的md5码
					filemd5 = getmd5(real_path)
					# 如果文件 md5 已存在,则删除此文件
					if filemd5 in all_md5.keys():  # 字典的键为文件 md5 码
						total_delete += 1
						print(f"删除:{file}")
						os.remove(real_path)
						#os.remove(path +"/" + file)  windows下这种也可以用
					else:
						# 如果文件 md5 不存在,则将此文件的 md5 码添加到 all_md5 字典中
						all_md5[filemd5] = ""
			# 结束时间
			end = time.time()
			time_last = end - start
			print('文件总数:', total_file)
			print('删除个数:', total_delete)
			print('耗时:', time_last, '秒')
			print(f"处理结束:{path}\n")

	print("批处理完成,返回主菜单\n")
	return


def getmd5(filename):
	"""
	功能:获取文件 md5 码
	:param filename: 文件路径
	:return: 文件 md5 码
	备注:文件过大有可能卡机
	"""
	file_txt = open(filename, 'rb').read()
	# 调用一个md5对象
	m = hashlib.md5(file_txt)
	# hexdigest()方法来获取摘要(加密结果)
	return m.hexdigest()

def show_help():
	helpstr = """
\n===============说明文本===============

脚本主要功能:
	删除指定的文件夹下的重复文件

脚本主要原理:
	计算每个文件的MD5值,并写入字典,然后查找去重

功能选择说明:
	在主菜单输入数字 0 1 2 3 并按回车后分别进入对应功能

1: 手动输入路径
	此功能需要自行输入需要去重的文件夹的完整路径
	也可以在文件管理器中复制完整路径粘贴后按回车

2: 读取批量文本
	此功能需要输入批量处理文本的完整路径
	比如Linux下:    /home/name/filelist.txt
	比如Windows下:  D:/filelists.txt
	注意1:批量处理文本的文件名可任意自取,比如上面所示的filelists.txt
	      但是对文件内容要求第一行必须为:
	      #filelist
	注意2:建议'#filelist'顶格无缩进,且编码保存为utf-8

	下面是Debian Linux下一个示例文本的完整内容:
		#filelist
		/home/name/桌面/231/
		/home/name/桌面/256/
		/home/name/WeChat Files/wxid/File/2022-10/
		/home/name/WeChat Files/wxid/File/2022-11/

	下面是Windows下一个示例文本的完整内容:
		#filelist
		E:/WeChat Files/wxid/File/2022-10
		E:/WeChat Files/wxid/File/2022-11

报告Bug:
	***@qq.com
===============说明文本===============\n
"""
	print(helpstr)
	return



def main():
	"""
	略
	"""

	choiceWhat()



if __name__ == '__main__':
	main()


# def get_filelists(file_dir="."):
# 	list_directory = os.listdir(file_dir)
# 	filelists = []
# 	for directory in list_directory:
# 		if(os.path.isfile(directory)):
# 			filelists.append(directory)
# 	return filelists

# def get_filelists2(file_dir):
# 	list_directory = os.listdir(file_dir)
# 	filelists = []
# 	for directory in list_directory:
# 		if(os.path.isfile(directory)):
# 			filelists.append(directory)
# 	return filelists

# def printNowDir():
# 	path3 = os.listdir(os.getcwd())
# 	for p in path3:
# 		if os.path.isdir(p):
# 			print(f"文件夹:{p}")
# 		if os.path.isfile(p):
# 			print(f"文件:{p}")

标签:文件,删除,重复,文件夹,file,print,path,os,md5
From: https://www.cnblogs.com/namevt/p/16861397.html

相关文章