7.4. glob — 文件名规则匹配
目的:使用 Unix shell 规则去查找匹配模式的文件。
尽管 glob
API 很少,但是功能强大。在那种需要查找系统上匹配一个模式的文件时非常有用。当需要去创建一个有某个相同扩展,前缀或者中间有共同字符串的文件列表时,应该考虑使用 glob
而不是自定义处理目录内容的代码。
glob
模块使用的模式规则不同于 re
模块使用的正则表达式。而是使用 Unix 路径扩展规则。只有少数特殊字符用去实现两个不同的通配符以及特殊字符。模式规则应用于文件名的段(以路径分隔符 /
为界)。模式中的路径可以是相对的或者绝对的。Shell 变量名和波浪符( ~
)不会被展开。
示例数据
假设这个例子中的测试文件是存在于当前工作目录的。
$ python3 glob_maketestdata.py
dir
dir/file.txt
dir/file1.txt
dir/file2.txt
dir/filea.txt
dir/fileb.txt
dir/file?.txt
dir/file*.txt
dir/file[.txt
dir/subdir
dir/subdir/subfile.txt
如果这些文件不存在,请在运行接下来例子之前使用示例代码中的 glob_maketestdata.py
创建它们。
通配符
一个星号( *
)匹配名称片段中零个或者多个字符,例如,dir/*
。
glob_asterisk.py
import glob
for name in sorted(glob.glob('dir/*')):
print(name)
这个模式匹配 「 dir
」目录中的每个路径名称(文件或者目录),但是不会进一步递归遍历子目录。glob
返回的数据是没有排序的,所以例子中对它进行排序以便更清楚地研究结果。
$ python3 glob_asterisk.py
dir/file*.txt
dir/file.txt
dir/file1.txt
dir/file2.txt
dir/file?.txt
dir/file[.txt
dir/filea.txt
dir/fileb.txt
dir/subdir
如果要查看子目录的内容,子目录必须包含在模式中。
glob_subdir.py
import glob
print('Named explicitly:')
for name in sorted(glob.glob('dir/subdir/*')):
print(' {}'.format(name))
print('Named with wildcard:')
for name in sorted(glob.glob('dir/*/*')):
print(' {}'.format(name))
前面显示的第一个例子中显示地列出了子目录名称,但是第二个依赖于通配符查找子目录。
$ python3 glob_subdir.py
Named explicitly:
dir/subdir/subfile.txt
Named with wildcard:
dir/subdir/subfile.txt
在这个示例中两种方式的结果是一样的。但是如果这里还有一个子目录,通配符将会匹配这两个子目录并包含这两个目录下的所有文件。
单字符通配符
问好( ?
)是另一个通配符。它匹配文件名称中任何单个字符。
glob_question.py
import glob
for name in sorted(glob.glob('dir/file?.txt')):
print(name)
前面的例子中匹配所有以 file
开始的文件,紧接着是一个任何类型的字符,然后以 .txt
结束。
$ python3 glob_question.py
dir/file*.txt
dir/file1.txt
dir/file2.txt
dir/file?.txt
dir/file[.txt
dir/filea.txt
dir/fileb.txt
字符范围
使用字符范围( [a-z]
)而不是问号去匹配多个字符中的一个。这个例子中将会查找到所有在扩展名之前有一个数字的文件。
glob_charrange.py
import glob
for name in sorted(glob.glob('dir/*[0-9].*')):
print(name)
字符范围 [0-9]
匹配一个数字。范围根据每个字母或者数字的字符代码进行排序,破折号表示字符的连续范围。[0-9]
等同于 [0123456789]
。
$ python3 glob_charrange.py
dir/file1.txt
dir/file2.txt
转义元字符
有时候可能需要去查找一些包含 glob
模式使用的特殊字符的文件。escape()
方法会用转义后的特殊字符构建一个适配模式,这样 glob
就不会将它当做特殊字符解释处理。
glob_escape.py
import glob
specials = '?*['
for char in specials:
pattern = 'dir/*' + glob.escape(char) + '.txt'
print('Searching for: {!r}'.format(pattern))
for name in sorted(glob.glob(pattern)):
print(name)
print()
通过构建包含单个字符的字符范围将每个特殊字符进行转义。
$ python3 glob_escape.py
Searching for: 'dir/*[?].txt'
dir/file?.txt
Searching for: 'dir/*[*].txt'
dir/file*.txt
Searching for: 'dir/*[[].txt'
dir/file[.txt
推荐阅读
- glob 标准库文档
- 模式匹配符号 -- 开放Shell 命令语言规范解释。
fnmatch
-- 文件名匹配实现。- glob python 2到3 移植笔记
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。