A、基础功能:
1、实现Windows系统下对文件和文件夹的批量重命名;
2、可由用户输入指定的目录路径;
3、可选择对文件、文件夹或所有对象进行重命名;
4、重命名的类型包括删除文件/文件夹名称中的指定字符串、给文件或文件夹的名称添加指定前缀、给文件或文件夹的名称添加制定后缀。B、进阶功能:
1、可对指定的后缀文件进行重命名;
2、实现通过密码认证后才能正常使用重命名程序,且输入密码时以‘*’隐藏;
3、使用pyinstaller将该Python程序打包成Windows的exe文件。C、打包exe:
1、安装pyinstaller;
2、打包命令pyinstaller -F FileRename.py
。D、说明:在PyCharm中不能运行,需在Windows命令行控制台运行py文件(因使用msvcrt模块的缘故)。
代码示例:
import os
import re
import msvcrt
def get_all_file(dir_path, file_list):
'''
通过递归获取dir_path目录下的所有文件和文件夹的绝对路径,添加到file_list列表中,并返回。
:param dir_path: (类型:字符串)指定目录的绝对路径
:param file_list: (类型:列表)存放文件和文件夹绝对路径的列表
:return: (类型:列表)返回file_list列表
'''
for file in os.listdir(dir_path):
file_path = os.path.join(dir_path, file) # 通过os.path.join()方法生成当前目录下的文件或文件夹的绝对路径
file_list.append(file_path) # 将获取到的file_path追加到file_list列表中
if os.path.isdir(file_path): # 判断当前获取到的file_path是否是目录,如果是目录,则继续递归
get_all_file(file_path, file_list) # 递归当前获取的file_path,并传入更新后的file_list
return file_list # 返回file_list列表
def filename_del_str(file_names, suffix, keyword, dir_or_file):
'''
删除文件名或文件夹名中的指定字符串keyword。
:param file_names: (类型:列表)指定目录下的所有文件和文件夹的绝对路径列表
:param suffix: (类型:字符串)指定的文件后缀字符串,用于筛选出特定类型的文件进行操作
:param keyword: (类型:字符串)指定需要删除的特定字符串
:param dir_or_file: (类型:字符串)指定操作对象是文件还是文件夹,all-代表所有对象,file-代表文件,dir-代表目录
:return: 无返回值
'''
for file in file_names:
check = os.path.join(os.path.abspath('.'), file)
if dir_or_file == 'all': # 判断指定的对象是否是所有对象
conditions = os.path.isfile(check) or os.path.isdir(check) # 两个条件,或关系,如果该对象是文件或文件夹,则返回True,否则,则返回False,赋值给conditions
elif dir_or_file == 'file': # 判断指定的对象是否是文件
conditions = os.path.isfile(check) # 如果该对象为文件,则返回True,否则,返回False,赋值给conditions
elif dir_or_file == 'dir': # 判断指定的对象是否是目录
conditions = os.path.isdir(check) # 如果该对象为文件夹,则返回True,否则,返回False,赋值给conditions
if conditions:
if len(suffix)==0 or suffix.isspace(): # 判断指定的文件后缀suffix的长度是否等于0或空格,如果是,则返回True,说明没有指定特定文件类型,将对所有对象进行操作
if keyword in file:
new_file = file.replace(keyword, '') # 使用replace()将file中存在的指定字符串用空字符串替代
print(file, " -> ", new_file)
os.rename(file, new_file) # 通过os.rename()对文件或文件夹进行重命名
for i in range(len(file_names)):
file_names[i] = file_names[i].replace(file, new_file) # 对file_names所有对象中存在的file均使用new_file替代
else:
if re.match('.+?\.'+suffix+'$', file) != None and keyword in file: # 用正则表达式匹配后缀名
new_file = file.replace(keyword, '')
print(file, " -> ", new_file)
os.rename(file, new_file)
for i in range(len(file_names)):
file_names[i] = file_names[i].replace(file, new_file)
def filename_add_str(file_names, suffix, keyword, location, dir_or_file):
'''
在文件名或文件夹名中添加指定字符串keyword。
:param file_names: (类型:列表)指定目录下的所有文件和文件夹的绝对路径列表
:param suffix: (类型:字符串)指定的文件后缀字符串,用于筛选出特定类型的文件进行操作
:param keyword: (类型:字符串)指定需要删除的特定字符串
:param location: (类型:字符串)指定给文件名或文件夹名添加前缀还是后缀,prefix-代表前缀,suffix-代表后缀
:param dir_or_file: (类型:字符串)指定操作对象是文件还是文件夹,all-代表所有对象,file-代表文件,dir-代表目录
:return: 无返回值
'''
file_names.reverse() # 将file_names列表进行反转,此目的是为了从最内层开始对文件或文件夹进行重命名,如果从外层向内层进行操作,在执行os.rename时就会存在找不到指定路径的错误
for file in file_names:
check = os.path.join(os.path.abspath('.'), file)
if dir_or_file == 'all':
conditions = os.path.isfile(check) or os.path.isdir(check)
elif dir_or_file == 'file':
conditions = os.path.isfile(check)
elif dir_or_file == 'dir':
conditions = os.path.isdir(check)
if conditions:
if len(suffix) == 0 or suffix.isspace():
if location == 'prefix': # 判断指定的location是否为前缀,如果是,则返回True,否则为False
file_path = os.path.dirname(file) # 通过os.path.dirname()获取file的目录路径,并赋值给file_path
base_name = os.path.basename(file) # 通过os.path.basename()获取file的名称,并赋值给base_name
new_name = keyword + base_name # 将keyword与base_name进行连接,得到新的file名称,并赋值给new_name
new_file = os.path.join(file_path, new_name)
print(file, " -> ", new_file)
os.rename(file, new_file) # 通过os.rename()对文件或文件夹进行重命名
elif location == 'suffix': # 判断指定的location是否为后缀,如果是,则返回True,否则为False
file_path = os.path.dirname(file)
file_name, ext = os.path.splitext(file)
base_name = os.path.basename(file_name)
new_name = base_name + keyword + ext
new_file = os.path.join(file_path, new_name)
print(file, " -> ", new_file)
os.rename(file, new_file)
else:
if re.match('.+?\.' + suffix + '$', file) != None: # 用正则表达式匹配后缀名
if location == 'prefix':
file_path = os.path.dirname(file)
base_name = os.path.basename(file)
new_name = keyword + base_name
new_file = os.path.join(file_path, new_name)
print(file, " -> ", new_file)
os.rename(file, new_file)
elif location == 'suffix':
file_path = os.path.dirname(file)
file_name, ext = os.path.splitext(file) # 通过os.path.splitext()将文件名和文件后缀切分,分别赋值给file_name和ext
base_name = os.path.basename(file_name)
new_name = base_name + keyword + ext # 将base_name、keyword、ext进行连接,得到新的file名称,并赋值给new_name
new_file = os.path.join(file_path, new_name)
print(file, " -> ", new_file)
os.rename(file, new_file)
def Input_string():
'''
引导用户输入需要删除或添加的字符串(keyword)。
:return: (类型:字符串)返回用户输入的字符串keyword
'''
flag = 1
while flag:
keyword = input("请输入字符串:") # 用户输入字符串,并赋值给keyword
if len(keyword) == 0 or keyword.isspace():
print("字符串不能为空,请重新输入!\n") # 判断keyword是否为空,如果为空,则提示用户重新输入
continue # 继续从头开始执行循环,让客户重新输入
while True:
'''
让客户确认输入的字符串是否是正确的,如果正确,则输入‘Y’,如果不正确,则输入‘N’,并回到输入的位置重新输入
输入的字母不区分大小写,直接回车代表输入'Y'
'''
confirm = input("请确认字符串是否为{},请回复'Y'或'N'(字母不区分大小写,直接回车代表'Y'):".format(repr(keyword))).strip()
if confirm.upper() == 'Y' or confirm == '':
flag = 0
break
elif confirm.upper() == 'N':
print('字符串不正确,需重新输入!\n')
break
else:
print('输入错误,请重新输入!\n')
continue
return keyword
def set_suffix():
'''
引导用户输入需要筛选的文件后缀(suffix)。
:return:
'''
flag = 1
while flag:
suffix = input("\n需要筛选的文件名后缀(直接回车代表所有):") # 用户输入字符串,并赋值给suffix,直接回车代表输入为空
while True:
'''
让客户确认输入的字符串是否是正确的,如果正确,则输入‘Y’,如果不正确,则输入‘N’,并回到输入的位置重新输入
输入的字母不区分大小写,直接回车代表输入'Y'
三元运算符:'所有' if suffix == '' else suffix,如果suffix为空,则将‘所有’输出到指定的位置,否则,则将suffix的内容输出到指定的位置
'''
confirm = input("\n请确认筛选的文件名后缀是否为'{}',请回复'Y'或'N'(字母不区分大小写,直接回车代表'Y'):".format('所有' if suffix == '' else suffix)).strip()
if confirm.upper() == 'Y' or confirm == '':
flag = 0
break
elif confirm.upper() == 'N':
print('要筛选的文件名后缀不正确,需重新输入!\n')
break
else:
print('输入错误,请重新输入!\n')
continue
return suffix
def is_finish(flag01, flag02, flag03):
'''
用于执行完每一次操作之后,让用户选择是否继续执行。
:param flag01: (类型:整型数值)第一层循环的标识
:param flag02: (类型:整型数值)第二层循环的标识
:param flag03: (类型:整型数值)第三层循环的标识
:return: (类型:元组)返回由flag01、flag02、flag03组成的元组
'''
while True:
is_continue = input("\n文件重命名完成!是否继续?请回复'Y'或'N'(字母不区分大小写,直接回车代表'Y'):").strip()
if is_continue.upper() == 'Y' or is_continue == '':
flag03 = 0 # 将第三层循环的标识赋值为0
break
elif is_continue.upper() == 'N':
flag01 = 0 # 将第一层循环的标识赋值为0
flag02 = 0 # 将第二层循环的标识赋值为0
flag03 = 0 # 将第三层循环的标识赋值为0
break
else:
print('输入错误,请重新输入!\n')
return flag01, flag02, flag03 # 返回由flag01、flag02、flag03组成的元组
def set_dif_or_file(flag01):
'''
引导用户选择操作的对象是所有对象,还是文件或文件夹。
:param flag01: (类型:整型数值)第一层循环的标识
:return:(类型:元组)返回由flag01、dir_or_file组成的元组
'''
while True:
'''
引导用户选择操作对象
1-代表所有对象,并将‘all’赋值给dir_or_file
2-代表文件,并将‘file’赋值给dir_or_file
3-代表文件夹,并将‘dir’赋值给dir_or_file
R-代表返回上一级
Q-代表结束程序
'''
dir_or_file = input('''\n选择列表如下:\n1: 所有\n2: 文件\n3: 文件夹\nR: 返回上一级\nQ: 退出\n\n请选择重命名文件还是目录(输入对应功能的编号即可,字母不区分大小写):''').strip()
if dir_or_file == '1':
dir_or_file = 'all'
break
elif dir_or_file == '2':
dir_or_file = 'file'
break
elif dir_or_file == '3':
dir_or_file = 'dir'
break
elif dir_or_file.upper() == 'R':
print('返回上一级!\n')
flag01 = -1 # 将第一层循环的标识赋值为-1
break
elif dir_or_file.upper() == 'Q':
flag01 = 0 # 将第一层循环的标识赋值为0
break
else:
print('输入错误,请重新输入!\n')
return flag01, dir_or_file # 返回由flag01、dir_or_file组成的元组
if __name__ == '__main__':
flag01 = 1
while flag01: # 第一层循环
count = 3
flag02 = 1
while flag02: # 第二层循环
flag02 = 1
print('请输入密码:', end='', flush=True)
password = []
while True: # 第三层循环
ch = msvcrt.getch()
# 退格
if ch == b'\x08':
if password:
password.pop()
msvcrt.putch(b'\b')
msvcrt.putch(b' ')
msvcrt.putch(b'\b')
# Esc
elif ch == b'\x1b':
break
elif ch == b'\r':
msvcrt.putch(b'\n')
password = b''.join(password).decode()
if password == '888888':
print('\n登录成功,开始运行...\n')
flag02 = 0
break
else:
count -= 1
if count == 0:
print('\n你的输入次数已用完!\n')
flag02 = 0
break
else:
print('\n你输入的密码不正确,你还有{}次输入机会,请重新输入!\n'.format(count))
flag02 = -1
break
else:
password.append(ch)
msvcrt.putch(b'*')
if count == 0:
break
elif flag02 == -1:
continue
flag03 = 1
while flag03: # 第二层循环
if count == 0:
break
dir_path = input("请输入路径(输入'Q'即可退出,字母不区分大小写,直接回车代表当前路径):").strip()
if dir_path.upper() == 'Q':
flag01 = 0
break
elif dir_path == '':
dir_path = os.getcwd()
elif not os.path.isdir(dir_path):
print('输入的路径不正确,请重新输入!')
continue
print("\n选择的路径为:'{}'".format(dir_path))
file_list = []
file_names = get_all_file(dir_path, file_list)
flag01, dir_or_file = set_dif_or_file(flag01)
if flag01 == 0:
break
elif flag01 == -1:
continue
suffix = ''
if dir_or_file != 'dir':
suffix = set_suffix()
flag04 = 1
while flag04: # 第三层循环
operation = input('''\n选择列表如下:\n1: 在文件名/文件夹名中删除指定的字符串\n2: 在文件名/文件夹名中增加指定的字符串\nR: 返回上一级\nQ: 退出\n\n请选择你要操作的功能(输入对应功能的编号即可,字母不区分大小写):''').strip()
if operation == '1':
keyword = Input_string()
filename_del_str(file_names, suffix, keyword, dir_or_file)
flag01, flag03, flag04 = is_finish(flag01, flag03, flag04)
elif operation == '2':
flag05 = 1
#
while flag05: # 第四层循环
location = input('''\n选择列表如下:\n1: 在文件名/文件夹名的开头增加指定字符串\n2: 在文件名/文件夹名的结尾增加指定字符串\nR: 返回上一级\nQ: 退出程序\n\n请选择你要操作的功能(输入对应功能的编号即可,字母不区分大小写):''').strip()
if location == '1':
location = 'prefix'
keyword = Input_string()
filename_add_str(file_names, suffix, keyword, location, dir_or_file)
flag01, flag03, flag04 = is_finish(flag01, flag03, flag04)
break
elif location == '2':
location = 'suffix'
keyword = Input_string()
filename_add_str(file_names, suffix, keyword, location, dir_or_file)
flag01, flag03, flag04 = is_finish(flag01, flag03, flag04)
break
elif location.upper() == 'R':
print('返回上一级!\n')
break
elif location.upper() == 'Q':
flag01 = 0
flag03 = 0
flag04 = 0
break
else:
print('输入错误,请重新输入!\n') #
elif operation.upper() == 'R':
print('返回上一级!\n')
break
elif operation.upper() == 'Q':
flag01 = 0
flag03 = 0
break
else:
print('输入错误,请重新输入!\n')
if flag03 == 0:
break
print('\n程序结束!')
Python实现-Windows下批量重命名文件和文件夹的源文件(包括py文件和exe文件)下载链接请关注微信公众号“全栈POT修炼”,并回复“8033”获取。
“全栈POT修炼”
转载请注明出处,原创来自于https://www.jianshu.com/p/b3331aed27ab
网友评论