当我们批量进行文件处理时,往往需要程序自动读取某一文件夹下某一类型的所有文件。
例如:当我们需要对文件夹下所有的 ∗ * ∗.tif 文件进行裁剪操作,此时,就需要找到文件夹下所有的 ∗ * ∗.tif 文件,然后逐个裁剪输出。因此,查找文件夹下所有的 ∗ * ∗.tif 文件是批量裁剪首要解决的问题。
本文提供两种批量查找文件的方法:1)一种采用os库来进行,2)另一种采用glob库(推荐方法)通过通配符的方式查找。并提供相应的基础示例,由简单到复杂,方便理解。除此之外,还针对两种库构造函数实例,实现获取全部文件夹、文件等多种高级搜索功能,甚至还能查找含有固定字符的文件或文件夹,方便应用时直接调用,简化应用过程。
目录
0 关键字
遍历,文件,os,glob,通配符
1 主要思路
2 示例数据
1)定义查找文件夹路径
Path = r'D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件'
注意: \为特殊字符,加上r后表示不进行转义,Python才能正常识别此路径。当然,路径表述还有其他的方式,例如:
利用 \\:Path = ‘D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件’
利用 / / /:Path = ‘D:/CSDN/Python系统交互/0 按指定规则查找目录下所有文件’
这几种方式等效。
2)示例文件组织方式
文件夹下有3个txt文件、1个csv文件和一个子文件夹 [其他],子文件夹 [其他] 下有一个txt文件和一个csv文件。文件组织方式如下:
0 按指定规则查找目录下所有文件
----其他
-------201805.txt
-------201806.csv
----201801.txt
----201802.txt
----201803.txt
----201804.csv
3 os方法
首先导入os库。
import os
3.1 基础:提取文件夹下指定扩展名的文件
任务目标:提取 [Path] 下所有 txt 文件(不包含子文件夹 [其他] 下的 txt 文件)。
预期结果:返回:
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201801.txt
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201802.txt
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201803.txt
1)获取所有文件和文件夹路径(不包括子文件夹下的项)
Files = os.listdir(Path)
2)获取所有 txt 文件
基础:利用for循环
NeedFiles = [] # 创建一个空列表存储最终的结果
for File in Files:
if File.endswith('.txt'):
# 通过os.path.join将Path与文件名File组合为完整文件路径,并将结果添加到NeedFilse
NeedFiles.append(os.path.join(Path,File))
print(NeedFiles)
优化:构造列表解析式
NeedFiles = [os.path.join(Path,File) for File in Files if File.endswith('.txt')]
print(NeedFiles)
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt']
3.2 进阶:提取文件夹及其子文件夹下所有指定扩展名的文件
任务目标:提取 [Path] 及其子文件夹 [其他] 下所有 txt 文件。
预期结果:返回:
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201801.txt
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201802.txt
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201803.txt
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\其他\201805.txt
基础:利用for循环
NeedFiles = []
for Root, Folders, FileNames in os.walk(Path):
for FileName in FileNames:
if FileName.endswith('.txt'):
NeedFiles.append(os.path.join(Root, FileName))
print(NeedFiles)
其中 Folders为子文件夹集合,FileNames为子文件集合。如果需要获取子文件夹,则将
for FileName in FileNames
部分改为for Folder in Folders
,按照需求判断即可。
练习1:利用 列表解析式 优化 本节提取过程。
练习2:获取所有子文件夹路径。
当然,正则表达式(regular expression) 也可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
探索:利用re库构建正则表达式匹配文件。有兴趣的朋友可以尝试。
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201805.txt']
3.3 高阶:构造 GetPath 函数实现获取全部文件夹、文件的功能
此函数可实现对1个或多个文件夹内(SearchPath)所需类型(SearchType)和指定扩展名(EXT)文件的查找,函数整体是对本章前两节所述内容的扩展,有兴趣的朋友可自行调用测试,也欢迎对其进行改造优化。
def GetPaths(SearchPath, SearchType = 'FILE', EXT = None):
'''
简介
----------
获取目标 【路径或路径集合】 下满足条件的所有 【文件夹或(和)文件路径】。
参数
----------
SearchPath: str 或 list。路径或路径列表。可以是:
1.路径(str)。 例:'C:/SP' 或 'C:/SP/test.txt'。
2.路径集合(list)。 例: ['C:/SD', 'C:/SP', 'C:/SP/test.txt']
注:如果目标路径或路径集合中包含文件,则会判断文件是否存在,如果文件不存在,返回结果会将此文件路径清除。
**可选参数
----------
SearchType = str。要查找路径的类型,默认为查找文件('FILE')。
其他类型包括'DIR'(文件夹),'ALL'(文件夹和文件)。如果设置的值不为以上所有类型,则认为是'ALL'。
EXT = str。查找文件的扩展名。只有在 SearchPath = 'FILE' 时, 此参数才生效。默认查找所有文件(None)。
返回
----------
类型:list。满足条件的所有 【文件夹和文件路径】集合。重复的路径只会保留一个。
'''
def GetALLPath(SearchPath): # 获取所有文件和文件夹路径。
PathsList = []
if isinstance(SearchPath, list) is False: # 如果参数不是列表,则将其转为列表
SearchPath = list([SearchPath])
for SubPath in SearchPath: # 遍历列表内所有项
if os.path.isdir(SubPath): # 如果是文件夹,则按照 4.2 的思路查找所有文件和文件夹
for Root, Folders, FileNames in os.walk(SubPath):
for Folder in Folders:
PathsList.append(os.path.join(Root, Folder))
for FileName in FileNames:
PathsList.append(os.path.join(Root, FileName))
else: # 如果是文件,且文件存在,则直接记录文件路径
if os.path.exists(SubPath):
PathsList.append(SubPath)
return list(set(PathsList))
def GetSubPath():
OutList = []
for Path in PathsList: # 遍历 PathsList 列表内的所有项
# 如果SearchType参数(忽略大小写)为'DIR'则记录文件夹。
if SearchType.upper() == 'DIR':
if os.path.isdir(Path):
OutList.append(Path)
else:
# 如果未设置扩展名则保留所有文件,否则保留指定扩展名的文件。
if os.path.isfile(Path):
if EXT is None:
OutList.append(Path)
else:
if Path.lower().endswith(EXT.lower()):
OutList.append(Path)
return OutList
PathsList = GetALLPath(SearchPath)
# 如果SearchType不为'DIR'或'FILE',则返回所有文件和文件夹路径(本例结果均包含子文件和子文件夹)。
if SearchType.upper() != 'DIR' and SearchType.upper() != 'FILE':
return PathsList
else:
return GetSubPath()
引用:
NeedFiles = GetPath(Path, EXT = '.txt')
print(NeedFiles)
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201805.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt']
4 glob方法(推荐)
首先导入os、glob库。
import os
import glob
4.1 入门:常用通配符简介
通配符 | 简介 |
---|---|
* | 匹配零个或多个字符,但不匹配"."开头的文件。 |
? | 仅匹配其中某一个单字符。 |
[] | 匹配括号内的任意单字符,可使用“-”符号表示一个范围。例如:[0-9]:匹配数字范围;[a-z]:匹配字母范围。 |
** | 匹配所有字符。glob进行递归操作时设置此通配符才能生效。 |
4.2 基础:使用通配符获取指定扩展名的文件
任务目标:提取 [Path] 下所有 csv 文件(不包含子文件夹 [其他] 下的 csv 文件)。
预期结果:返回:
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201804.csv
Files = glob.glob(Path+'\*.csv')
print(Files)
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv']
4.3 进阶:使用通配符获取文件夹及子文件下指定扩展名的文件
任务目标:提取 [Path] 及其子文件夹 [其他] 下所有 csv 文件。
预期结果:返回:
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201804.csv
D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\其他\201806.csv
Files = glob.glob(Path+'\**\*.csv', recursive = True) # recursive 是否进行递归。
print(Files)
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201806.csv']
4.4 高阶:利用glob库构造GetPath函数实现高级查找功能
推荐使用该函数实现查找功能。该函数可以以一个或多个文件夹为查找目标(Path),实现文件、文件夹、文件和文件夹查找(Search);查找文件时可提供扩展名(EXT),获取目标类型的文件;同时,也能够根据文件包含的字符串(String),实现精确查找。当然,EXT和String参数也可为列表,实现多类型,多字符串的同时匹配,满足多种查找需求。另外,如果大家有其他更好的想法,也欢迎反馈和讨论。
def GetPath(Path, Search = 'FILE', EXT = None, String = None):
'''
简介
----------
获取目标 【路径或路径集合】 下满足条件的所有 【文件夹和(或)文件路径】。
参数
----------
Path: str 或 list。路径或路径集合。可以是:
1.路径(str)。 例:'C:/SP'。
2.路径集合(list)。 例: ['C:/SD', 'C:/SP']
**可选参数
----------
Search = 'FILE' 或其他类型。要查找路径的类型,默认为查找文件('FILE')。
其他类型包括'DIR'(文件夹),'ALL'(文件夹和文件)。如果设置的值不为以上所有类型,则认为是 'FILE' 。
EXT = None 或 str、list。查找文件的扩展名或扩展名列表。只有在Search = 'FILE'时, 此参数才生效。默认查找所有文件(None)。
String = None 或 str、list。查找的文件路径中包含的字符串或字符串列表。默认不处理此参数(None)。
返回
----------
类型:list。满足条件的所有 【文件夹和文件路径】集合。
'''
# 格式化输入目录
if isinstance(Path, str):
Path = [Path]
elif isinstance(Path, list):
Path = list(set(Path))
else:
return []
# 格式化通配符规则
if Search == 'DIR':
Wildcard = '/**/'
elif Search == 'ALL':
Wildcard = '/**/*'
else:
if EXT is None:
Wildcard = '/**/*.*'
elif isinstance(EXT, list):
Wildcard = ['/**/*' + E for E in EXT]
else:
Wildcard = '/**/*' + EXT
# 通配所有路径
if isinstance(Wildcard, list):
SPath = sum([glob.glob(P + W, recursive = True) for P in Path for W in Wildcard if os.path.exists(P)], [])
else:
SPath = sum([glob.glob(P + Wildcard, recursive = True) for P in Path if os.path.exists(P)], [])
# 提取含设定字符串的路径
if String is not None:
if isinstance(String, str):
String = [String]
SPath = [P for P in SPath for S in String if S in os.path.basename(P)]
return SPath
引用:
NeedFiles = GetPath(Path, EXT = '.csv')
print(NeedFiles)
打印结果:
['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv',
'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201806.csv']