说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 中,glob 模块用于检索与指定模式匹配的文件/路径名。glob 的模式规则遵循标准的 Unix 路径扩展规则。据测试,它比其他方法更快地匹配目录中的路径名。使用 glob,除了精确的字符串搜索之外,我们还可以使用通配符("*, ?, [ranges])
,以使路径检索更加简单和方便。
glob 模块是最简单的模块之一,功能非常专一,用它可以查找符合特定规则的文件路径名。
支持的通配符:
*
:星号 *
匹配一个文件名段中的0个或多个字符?
:问号?会匹配文件名中该位置的单个字符[]
:指定范围内的字符,如:[0-9] 匹配数字,[a-z] 匹配字母,再如 [5-8]、[a-c][!]
:不在一定范围内的字符,如 [!xls] 文件路径不包含 xls 的文件**
,所有目录,需要参数 recursive=True
示例:
# 匹配所有具有 pdf 扩展名的文件
*.pdf
# 匹配sales文件夹中存在两个字符的所有文件
sales/??.jpeg
# 匹配以字母 p、s 或 r 开头的文件
[psr]*
# 匹配不以字母p、s或r开头的文件
[!psr]*
以下是简单的使用方法:
import glob
# 注意,以下返回的均是一个列表
# 找到精确的文件
glob.glob('/Users/hui/Downloads/te.csv')
# ['/Users/hui/Downloads/te.csv']
# 使用*通配符,多个字符,所有 csv 扩展名文件
glob.glob('/Users/hui/Downloads/*.csv')
# 用问号 '?' 通配符,代表一个字符
glob.glob('/Users/hui/Downloads/t?.csv')
# 用 [0-9] 通配,匹配数字
glob.glob('/Users/hui/Downloads/*[0-9].*')
# 如果以上通配符在文件的名称需要用 \ 转义
glob.glob('/Users/hui/Downloads/t\?.csv')
# Downloads 目录下所有子目录中 mp4 文件
glob.glob('/Users/hui/Downloads/*/*.mp4')
# Downloads 目录下所有子目录中(所有层级) mp4 文件
glob.glob('/Users/hui/Downloads/**/*.mp4', recursive=True)
# iglob 返回的是一个可迭代对象
glob.iglob('/Users/hui/Downloads/t\?.csv')
# <generator object _iglob at 0x7fc7230cc3c0>
glob 返回一个要查找的文件路径列表,语法为:
glob.glob(pathname,
*,
root_dir=None,
dir_fd=None,
recursive=False)
参数为:
**
将匹配任何文件以及零个或多个目录、子目录和符号链接返回:
与路径名模式匹配的路径列表。返回匹配 pathname 的可能为空的路径名列表,其中的元素必须为包含路径信息的字符串。
说明:
*
和 ?
匹配**
模式可能会消耗非常多的时间**
的递归 glob语法为 glob.iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False)
,返回一个 iterator,它会产生与 glob() 相同的结果,但不会实际地同时保存它们。
为什么用 iglob() ?
在某些情况下,要匹配的文件或文件夹数量很多,使用 glob() 加载这些文件或文件夹可能会占用内存。与使用 iglob() 则不用,您可以以迭代器对象的形式获得所有匹配的文件名,这将提高性能。
这意味着,iglob() 返回一个可调用的对象,调用该对象时会将结果加载到内存中。我们可以通过两种方式循环浏览文件夹和子文件夹以获取文件列表。
import glob
# using iglob
for item in glob.iglob("*.txt"):
print(item)
# check type
type(glob.glob("*.txt"))
# <class 'list'>
iglob()
type(glob.iglob("*.txt"))
# <class 'generator'>
除了字符和数字范围之外,我们还有 escape() 方法来启用 glob() 中带有特殊字符的模式,特别适用于带有特殊字符的文件名。
语法为 glob.escape(pathname)
,转义所有特殊字符 (?
、*
和 [
)。 这适用于当你想要匹配可能带有特殊字符的任意字符串字面值的情况。
正如函数名所示,此方法会转义参数中传递的路径名中的特殊字符。此函数用于搜索带有特殊字符的文件名,如 _, #, $
等。
在搜索带有特殊字符的文件名时,我们可以将此方法与 glob() 一起使用。让我们看一个例子来查找名称中带有特殊字符的文件。
import glob
print("All JPEG's files")
print(glob.glob("*.jpeg"))
print("JPEGs files with special characters in their name")
# set of special characters _, $, #
char_seq = "_$#"
for char in char_seq:
esc_set = "*" + glob.escape(char) + "*" + ".jpeg"
for file in (glob.glob(esc_set)):
print(file)
'''
All JPEG's files
['abc.jpeg', 'y_.jpeg', 'z$.jpeg', 'x#.jpeg']
JPEGs files with special characters in their name
y_.jpeg
z$.jpeg
x#.jpeg
'''
在 drive/UNC 共享点中的特殊字符不会被转义,例如在 Windows 上 escape(//?/c:/Quo vadis?.txt
) 将返回//?/c:/Quo vadis[?].txt
。这是3.4 新版功能。
其他属性方法有:
dir(glob)
'''
['__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dir_open_flags',
'_glob0',
'_glob1',
'_glob2',
'_iglob',
'_isdir',
'_ishidden',
'_isrecursive',
'_iterdir',
'_join',
'_lexists',
'_listdir',
'_rlistdir',
'contextlib',
'escape',
'fnmatch',
'glob',
'glob0',
'glob1',
'has_magic',
'iglob',
'itertools',
'magic_check',
'magic_check_bytes',
'os',
're',
'stat',
'sys']
'''
例如,考虑一个包含以下内容的目录:文件 1.gif, 2.txt, card.gif 以及一个子目录 sub 其中只包含一个文件 3.txt. glob() 将产生如下结果。 请注意路径的任何开头部分都将被保留。
>>> import glob
>>> glob.glob('./[0-9].*')
['./1.gif', './2.txt']
>>> glob.glob('*.gif')
['1.gif', 'card.gif']
>>> glob.glob('?.gif')
['1.gif']
>>> glob.glob('**/*.txt', recursive=True)
['2.txt', 'sub/3.txt']
>>> glob.glob('./**/', recursive=True)
['./', './sub/']
如果目录包含以 . 打头的文件,它们默认将不会被匹配。 例如,考虑一个包含 card.gif 和 .card.gif 的目录:
>>> import glob
>>> glob.glob('*.gif')
['card.gif']
>>> glob.glob('.c*')
['.card.gif']
我们可以使用 glob 模块搜索具有不同扩展名的文件。例如,您希望找到具有 .pdf 或 .txt 扩展名的文件。
import glob
# All pdf and txt files
extensions = ('*.ipynb', '*.csv')
files_list = []
# [files_list.extend(glob.glob(ext)) for ext in extensions]
for ext in extensions:
files_list.extend(glob.glob(ext))
files_list
'''
...
'''
glob() 函数在内部调用 fnmatch。fnmatch 仅使用以下四条规则进行模式匹配。如果您想用更灵活的规则扩展文件匹配,我们可以将 glob 与正则表达式结合起来。
考虑一个具有 JPEG 文件的雇员文件夹,我们要搜索一个名字与用户输入匹配的雇员。我们可以提到glob必须搜索的文件夹名,然后使用 regex 搜索模式进行搜索。
import glob
import re
num = input('Enter the employee number ')
# [a-z] for any employee name
# {file_name} is the employee number
regex = r'[a-z_]+{file_num}.*'.format(file_num=num)
# search emp jpeg in employees folder
for file in glob.glob("2020/*"):
if re.search(regex, file):
print('Employee Photo:', file)
'''
Enter the employee number 3
Employee Photo: 2020\emp_3.jpeg
'''
scandir() 和 glob() 函数都在内部搜索与特定模式匹配的目录中的文件。但是 scandir() 是一个返回迭代器对象的生成器函数,glob() 方法返回一个消耗大量内存的列表,可以用 iglob() 。
glob 是通过配合使用 os.scandir()
和 fnmatch.fnmatch()
函数来实现的,而不是通过实际发起调用子终端。 请注意不同于 fnmatch.fnmatch()
,glob 会将以点号 (.) 开头的文件名作为特殊情况来处理。 对于波浪号和终端变量扩展,请使用 os.path.expanduser()
和 os.path.expandvars()
。
更新时间:2022-01-25 16:51:46 标签:python 文件 文件夹