Python 深入浅出:用 fnmatch 与 glob 优雅搞定通配符文件检索
在进行运维脚本编写、数据分析预处理或者自动化文件整理时,我们最常遇到的需求之一就是文件检索。比如:找出目录下所有 .csv 后缀的文件、匹配所有以 log_2026_ 开头的文件,或者是递归搜索子目录下的所有 Python 脚本。
虽然正则表达式(re 模块)无所不能,但在文件路径匹配这种场景下,正则的语法过于繁复,且可读性较差。
在 Unix/Linux Shell 中,我们常用简单的通配符(Globbing Patterns)进行匹配。而在 Python 中,标准库提供了两个专门处理通配符的高效工具:fnmatch 与 glob。
本文将带您了解这两个模块的使用场景与实战技巧。
一、 通配符语法速成
与复杂的正则相比,通配符语法非常轻量且易记:
| 通配符 | 匹配规则 | 示例 |
|---|---|---|
* |
匹配任意长度的任意字符(包括空字符) | *.txt 匹配所有文本文件 |
? |
匹配单个任意字符 | image_?.png 匹配 image_1.png 但不匹配 image_10.png |
[seq] |
匹配字符序列 seq 中的任意一个字符 |
data_[0-9].csv 匹配 data_5.csv |
[!seq] |
匹配任何不在字符序列 seq 中的单个字符 |
temp_[!0-9].log 匹配 temp_a.log |
二、 纯文本模式匹配:fnmatch 模块
fnmatch 模块专门用于处理单纯的字符串通配符匹配。它不会访问真实的硬盘文件系统,只是进行单纯的文本计算。
核心方法:
fnmatch.fnmatch(filename, pattern):- 作用:判断
filename字符串是否匹配pattern。 - 特点:大小写敏感度会自动跟随操作系统(在 Windows 上不区分大小写,在 Linux/macOS 上区分大小写)。
fnmatch.fnmatchcase(filename, pattern):- 作用:在所有操作系统上强制区分大小写进行匹配。
fnmatch.filter(names, pattern):- 作用:从一个字符串列表中,直接过滤并返回所有符合通配符规则的子列表。
import fnmatch
files = ["data_1.csv", "DATA_2.CSV", "config.ini", "temp.log"]
# 强制区分大小写过滤以大写 DATA 开头的文件
matched = fnmatch.filter(files, "DATA_*.CSV")
print("匹配结果:", matched) # 输出: ['DATA_2.CSV']
三、 真实文件系统检索:glob 模块
与 fnmatch 不同,glob 是一个会真正扫描磁盘文件系统的模块。它结合了 fnmatch 的通配符计算与 os.listdir() 的目录扫描能力。
核心用法展示:
1. 基础匹配
import glob
# 找出当前目录下所有的 .py 文件
py_files = glob.glob("*.py")
print("当前目录 Python 文件:", py_files)
2. 深度递归检索(recursive=True)
如果你想扫描当前目录及其所有子目录下的特定文件,需要配合通配符 **,并显式设置 recursive=True:
# 递归找出 src 目录下所有子目录中的所有 .json 配置文件
config_files = glob.glob("src/**/*.json", recursive=True)
3. 海量文件防内存暴涨:iglob
glob.glob() 会将所有匹配的路径一次性加载到内存列表里。如果目录下有数百万个日志文件,会导致内存瞬间爆棚。
此时应使用 glob.iglob(),它会返回一个生成器(Generator),按需迭代产出路径,内存占用接近为 0:
# 返回迭代器,极其节省内存
log_generator = glob.iglob("logs/**/*.log", recursive=True)
for log_path in log_generator:
# 逐个处理,不占用大块内存
process_log(log_path)
四、 总结与最佳实践
- 单纯字符串对比,选
fnmatch:比如你在扫描目录时已经用os.walk拿到了文件列表,仅需要判断后缀或名称特征。 - 扫描硬盘,首选
glob:特别是需要进行递归子目录深度匹配时,使用glob.glob("**/...", recursive=True)或其迭代器版本iglob。 - 现代替代方案
pathlib:在 Python 3 中,标准库pathlib的Path对象也内置了Path.glob()和Path.rglob(),它们的底层调用的依然是glob模块的引擎。
灵活运用这两个通配符匹配工具,能够极大精简您的文件清理、日志归档以及自动化部署脚本,让文件检索变得优雅而高效!
本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。



暂无评论
还没有人评论过本文,快来发表你的高见吧!