使用python自动化处理文件夹,介绍了三个内容:
(1)使用python递归获取文件夹内嵌套子文件和子文件夹路径;
(2)使用python删除文件夹内(也适用于文件夹内可以包括多个嵌套子文件夹的情况)内容相同的重复文件(包括文件名不一样但是内容一样的也可以删除);
(3)自动整理文件,将文件夹内(也适用于文件夹内可以包括多个嵌套子文件夹的情况)不同类型的文件按照后缀名分类整理到不同的分类文件夹内。
这三部分内容可以一起使用,可以自动整理目标文件夹内的文件,然后再删除内容相同的文件。
主要使用的库包括:pandas, os, glob, filecmp, shutil
(1)递归获取文件夹内所有目录列表
思路:使用递归的方法实现,定义一个函数,使用os.listdir()获取某一级目录下的子目录,判断子目录是否为文件夹,若为文件夹,则递归调用该函数,若为文件,则保存该目录。
- 首先导入需要的库:pandas和os
import os
import pandas as pd
- 定义一个存储目录的列表
path_list = [] # 定义存储路径的列表
- 定义获取某一级目录下子目录的函数
def list_all_path(path):
if os.path.isdir(path): # 判断给定路径是否为目录
try: # 捕获可能会产生的异常
for per_path in os.listdir(path): # 迭代所有目录列表
list_all_path(os.path.join(path, per_path)) # 递归列出完整路径
except PermissionError as err: # 防止某些目录无法列出所造成的权限异常
pass
else:
global path_list # 使用glob声明path_list为全局变量
path_list.append(os.path.normpath(path)) # 使用os.path.normpath()对给定路径进行格式化处理
- 递归调用list_all_path函数
if __name__=='__main__':
goal_path = 'D:/华为云盘/毕业设计/参考文献' # 使用的是本人电脑上的目录,可自行更改
list_all_path(goal_path)
pd.Series(path_list).to_csv('./list.csv', encoding='utf_8_sig') # 将列表转换为Pandas的Series类型存储到csv文件中
# encoding格式设置为'utf_8_sig',否则会出现中文乱码问题,亲测'utf_8'无效
其实也可以使用os.walk()列出目录,会比递归的方法更加简便
(2)自动清理电脑内重复文件
思路:遍历获取给定文件下的所有文件,然后通过嵌套循环两两比较文件是否相同,若相同则删除后者
- 首先导入需要的库:glob和os和filecmp
import os
import glob
import filecmp
- 定义需要的路径和列表
# 需要清理的目标文件夹
dir_path = 'C:/Users/wyh/Desktop/参考文献'
# 存储文件绝对路径的列表
file_list = []
- 遍历获取所有文件的绝对路径,存储至列表file_list中
for file in glob.glob(os.path.join(dir_path, '**', '*'), recursive=True):
# file可能为文件也可能为文件夹,判断file是否为文件,若file为文件,存储文件的绝对路径至file_list列表中
if os.path.isfile(file):
file_list.append(file)
- 第二步:遍历列表file_list,比较列表中的文件是否相同,若相同,则删除
for file_a in file_list:
for file_b in file_list:
# 判断两个路径file_a和file_b是否一致,不一致则进行比较
# 考虑对列表进行循环嵌套,如果在前面循环中有文件已经被删除,后续比较会报错,因此需要判断文件是否存在
if file_a != file_b and os.path.exists(file_a) and os.path.exists(file_b):
if filecmp.cmp(file_a, file_b):
# 比较两个文件内容是否相同,若相同,则删除后者
os.remove(file_b)
(3)自动整理文件(根据文件后缀名区分种类)
思路:先获取目标文件夹内所有的文件路径,然后根据文件后缀名不同将其分到不同的分类文件夹内。
- 首先导入需要的库:glob和os和filecmp
import os
import shutil
import glob
- 设置文件夹路径(以下路径是本人电脑上的路径,可以根据自己的电脑自行更改)
# 设置一个存储分类后的文件的母文件夹路径
dir_path = r'C:\Users\wyh\Desktop\goal_file'
# 设置需要整理的目标文件夹路径
goal_path = r'C:\Users\wyh\Desktop\参考文献\剂量计算'
# 进行判断,如果dir_path不存在,则创建该文件夹
if not os.path.exists(dir_path):
os.mkdir(dir_path)
- 定义变量记录分类的文件和分类后的文件夹的数量
file_num = 0
dir_num = 0
- 核心循环部分
# 对目标文件夹进行遍历,获取所有子文件和子文件夹路径列表
# 然后对获取的路径列表进行判断,如果为文件的路径则获取文件名和后缀
for file in glob.glob(os.path.join(goal_path, '**', '*'), recursive=True):
if os.path.isfile(file):
filename = os.path.basename(file)
if '.' in filename:
# 使用-1索引被'.'拆分的最后一位,主要是担心文件名中有多个'.',split会按照'.'进行全部拆分
suffix = filename.split('.')[-1]
else:
suffix = 'others'
# 判断存储分类文件的子文件夹是否存在,若不存在,则创建,并将文件复制进去
if not os.path.exists(os.path.join(dir_path, suffix)):
os.mkdir(os.path.join(dir_path, suffix))
dir_num += 1
shutil.copy(file, os.path.join(dir_path, suffix))
file_num += 1
print('整理完成,将%d个文件整理到了%d个文件夹内' % (file_num, dir_num))
- 下面是我整理的结果,用于测试的文件类型比较少,分成了jpg、pdf、png三类
下面将代码整理,完整代码如下
import os
import pandas as pd
import shutil
import glob
import filecmp
path_list = [] # 定义存储路径的列表
def list_all_path(path):
'''
函数功能:某一级目录下的子目录路径
:param path: 某一级目录列表的文件夹路径
'''
if os.path.isdir(path): # 判断给定路径是否为目录
try: # 捕获可能会产生的异常
for per_path in os.listdir(path): # 迭代所有目录列表
list_all_path(os.path.join(path, per_path)) # 递归列出完整路径
except PermissionError as err: # 防止某些目录无法列出所造成的权限异常
pass
else:
global path_list # 使用glob声明path_list为全局变量
path_list.append(os.path.normpath(path)) # 使用os.path.normpath()对给定路径进行格式化处理
def List_All_Path(goal_path):
'''
函数功能:获取目标文件夹下所有嵌套子目录的路径列表并保存是csv文件内
:param goal_path: 待列出所有目录列表的文件夹路径
'''
list_all_path(goal_path)
pd.Series(path_list).to_csv('./list.csv', encoding='utf_8_sig') # 将列表转换为Pandas的Series类型存储到csv文件中
# encoding格式设置为'utf_8_sig',否则会出现中文乱码问题,亲测'utf_8'无效
def clear_same_file(dir_path):
'''
程序逻辑:遍历获取给定文件下的所有文件,然后通过嵌套循环两两比较文件是否相同,若相同则删除后者
函数功能:清理指定目标文件夹内包括嵌套子文件内所有重复的子文件
:param dir_path: 清理的目标文件夹路径
'''
# 存储文件绝对路径的列表
file_list = []
# 第一步:遍历获取所有文件的绝对路径,存储至列表file_list中
for file in glob.glob(os.path.join(dir_path, '**', '*'), recursive=True):
# file可能为文件也可能为文件夹,判断file是否为文件,若file为文件,存储文件的绝对路径至file_list列表中
if os.path.isfile(file):
file_list.append(file)
# 第二步:遍历列表file_list,比较列表中的文件是否相同,若相同,则删除
for file_a in file_list:
for file_b in file_list:
# 判断两个路径file_a和file_b是否一致,不一致则进行比较
# 考虑对列表进行循环嵌套,如果在前面循环中有文件已经被删除,后续比较会报错,因此需要判断文件是否存在
if file_a != file_b and os.path.exists(file_a) and os.path.exists(file_b):
if filecmp.cmp(file_a, file_b):
# 比较两个文件内容是否相同,若相同,则删除后者
os.remove(file_b)
def classify_file(dir_path, goal_path):
'''
函数功能:自动整理文件,给定一个待整理的文件夹,可以选出该目录下的所有文件,并且根据后缀名归类到不同的文件夹内
:param dir_path: 存储分类后的文件的母文件夹路径
:param goal_path: 需要整理的目标文件夹路径
'''
# 进行判断,如果dir_path不存在,则创建该文件夹
if not os.path.exists(dir_path):
os.mkdir(dir_path)
file_num = 0
dir_num = 0
# 对目标文件夹进行遍历,获取所有子文件和子文件夹路径列表
# 然后对获取的路径列表进行判断,如果为文件的路径则获取文件名和后缀
for file in glob.glob(os.path.join(goal_path, '**', '*'), recursive=True):
if os.path.isfile(file):
filename = os.path.basename(file)
if '.' in filename:
# 使用-1索引被'.'拆分的最后一位,主要是担心文件名中有多个'.',split会按照'.'进行全部拆分
suffix = filename.split('.')[-1]
else:
suffix = 'others'
# 判断存储分类文件的子文件夹是否存在,若不存在,则创建,并将文件复制进去
if not os.path.exists(os.path.join(dir_path, suffix)):
os.mkdir(os.path.join(dir_path, suffix))
dir_num += 1
shutil.copy(file, os.path.join(dir_path, suffix))
file_num += 1
print('整理完成,将%d个文件整理到了%d个文件夹内' % (file_num, dir_num))