◎代码文件:批量整理文件.py
◎数据文件:销售表(文件夹)
本节要对前面所学的知识进行综合应用,编写一个批量整理文件的程序。
下左图所示为文件夹“F:\销售表”中的一批文本文件,按月份存放在不同的子文件夹中,文件主名为分店名。现在要按分店名建立子文件夹分类组织这些文件,并对文件进行重命名,文件主名中要体现年份和月份信息(以文件的最近修改时间为准),同时将扩展名由“.txt”修改为“.csv”,效果如下右图所示。
根据前面的设定编写代码如下:
1 from pathlib import Path # 导入pathlib模块中的Path对象 2 from datetime import datetime # 导入datetime模块中的datetime对象 3 root_folder = Path('F:\\销售表') # 指定一个文件夹的路径 4 file_list = root_folder.rglob('*.txt') # 罗列指定文件夹中的文本文件 5 for f in file_list: # 遍历罗列结果 6 if f.is_dir(): # 如果路径指向的是文件夹 7 continue # 提前结束本轮循环 8 new_folder = root_folder / f.stem # 构造新的子文件夹路径,用分店名称命名 9 if not new_folder.exists(): # 如果新的子文件夹不存在 10 new_folder.mkdir(parents=True) # 创建该子文件夹 11 file_time = f.stat().st_mtime # 获取文件的状态信息并提取最近修改时间 12 file_time = datetime.fromtimestamp(file_time) # 将提取的时间转换为当前操作系统时区的时间 13 file_time = file_time.strftime('%Y年%m月') # 修改时间格式 14 new_file_name = file_time + '-' + f.name # 构造新的文件名 15 new_path = new_folder / new_file_name # 构造新的文件路径 16 new_path = new_path.with_suffix('.csv') # 修改文件路径中的文件扩展名 17 f.replace(new_path) # 根据构造的路径对文件进行重命名和移动 18 folder_list = root_folder.iterdir() # 罗列指定文件夹的内容 19 for f in folder_list: # 遍历罗列结果 20 if f.is_file(): # 如果路径指向的是文件 21 continue # 提前结束本轮循环 22 fc = len(list(f.iterdir())) # 罗列路径指向的子文件夹的内容,并统计其个数 23 if fc == 0: # 如果个数为0,说明子文件夹为空文件夹 24 f.rmdir() # 删除该子文件夹
第3~17行代码用于创建新的子文件夹,将文本文件分别移动进去并按要求进行重命名。第18~24行代码用于删除剩余的空文件夹。下面分别讲解其中的重点代码。
第4行代码将文件夹“F:\销售表”下所有扩展名为“.txt”的子文件夹或文件的路径都罗列出来,因为这里有多级文件夹,所以使用的是rglob()函数。
第5行代码用for语句构造一个循环,从罗列结果中逐个取出路径进行处理。
取出的路径有可能指向文件,也有可能指向子文件夹,而这里只对文件做操作,所以用第6行和第7行代码将罗列结果中的子文件夹排除掉。
第8行代码从路径中提取文件主名(即分店名),并利用文件主名构造新的分类文件夹路径。假设此时的变量f为路径“F:\\销售表\\2月销售统计\\成都分店.txt”,则f.stem为“成都分店”,而变量root_folder为路径“F:\\销售表”。用路径拼接运算符“/”将变量root_folder和f.stem拼接在一起,就得到了路径“F:\\销售表\\成都分店”,然后赋给变量new_folder。
第9行和第10行代码判断变量new_folder指向的文件夹是否不存在,如果不存在,则创建该文件夹。创建好新的分类文件夹后,接下来开始为文件构造新的文件名和路径。
第11行代码先调用路径对象的stat()函数获取文件的状态信息,再调用st_mtime属性从状态信息中提取文件的最近修改时间(时间戳)。第12行代码调用datetime对象的fromtimestamp()函数将时间戳转换为当前操作系统时区的时间。第13行代码调用strftime()函数将时间转换为“××××年××月”的格式。第14行代码将几个字符串拼接起来,得到新的文件名,如“2021年02月-成都分店.txt”。
第15行代码用“/”运算符将新文件名拼接到分类文件夹的路径后,得到新的文件路径,如“F:\\销售表\\成都分店\\2021年02月-成都分店.txt”。第16行代码用with_suffix()函数将新文件路径中的扩展名修改为“.csv”,如“F:\\销售表\\成都分店\\2021年02月-成都分店.csv”。
得到新文件路径后,第17行代码用replace()函数根据这个路径对文件进行重命名和移动。
第3~17行代码运行完毕后,实际上已经完成了文件的分类整理和重命名,但原先的“1月销售统计”“2月销售统计”“3月销售统计”等文件夹变成了空文件夹,已经没有用处,可以删除。第18~24行代码就是用来做这件事的。
第18行代码将文件夹“F:\销售表”下的所有子文件夹或文件的路径都罗列出来,因为这里只需要进行一级罗列,所以使用的是iterdir()函数。
第19行代码用for语句构造一个循环,从罗列结果中逐个取出路径进行处理。
取出的路径有可能指向文件,也有可能指向子文件夹,而这里只对子文件夹做操作,所以用第20行和第21行代码将罗列结果中的文件排除掉。
第22行代码再次使用iterdir()函数罗列子文件夹的内容,并用list()函数将罗列结果转换为列表,用len()函数统计列表元素的个数,得到子文件夹内容的个数。
第23行代码判断个数是否为0,如果为0,说明子文件夹是空文件夹,则执行第24行代码,用rmdir()函数将该子文件夹删除。