【Python】import os, glob, fnmatch--Python os/glob/fnmatch主要函數總結

import os, glob, fnmatch

auther: Lart
date: 2019-01-17
update: 2019-01-18 09:55:36html

針對某些操做, 官方推薦這些操做node

This module provides a portable way of using operating system dependent functionality.python

  • If you just want to read or write a file see open()
  • if you want to manipulate paths, see the os.path module
  • if you want to read all the lines in all the files on the command line see the fileinput module
  • for creating temporary files and directories see the tempfile module
  • for high-level file and directory handling see the shutil module.

環境變量

  • os.environ
  • os.getenv(key, default=None)
# 在操做系統中定義的環境變量,所有保存在os.environ這個變量中,能夠直接查看:

>>> os.environ
environ({...'LD_LIBRARY_PATH': '/usr/local/cuda-9.0/lib64:/usr/local/cuda-9.0/lib64', ..., 'LC_IDENTIFICATION': 'zh_CN.UTF-8', ...})


# 要獲取某個環境變量的值,能夠調用以下操做:
>>> os.environ['MANPATH']
'/home/lart/texlive/2018/texmf-dist/doc/man:/usr/local/man:'
>>> os.environ.get('MANPATH')
'/home/lart/texlive/2018/texmf-dist/doc/man:/usr/local/man:'
>>> os.environ.get('MANPATH', 'not found')
'/home/lart/texlive/2018/texmf-dist/doc/man:/usr/local/man:'
>>> os.environ.get('MAINPATH', 'not found')
'not found'
>>> os.environ('MAINPATH')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '_Environ' object is not callable

>>> os.getenv('MANPATH')
'/home/lart/texlive/2018/texmf-dist/doc/man:/usr/local/man:'
>>> os.getenv('MAINPATH', "not found")
'not found'
# os.getenv最大的差別就在於不存在路徑的時候, 不會引起異常
>>> os.getenv('MAINPATH')

系統指令

  • os.system(command)
    • 返回值只會有0(成功), 1, 2
  • os.popen(command)
    • 把執行的cmd的輸出做爲值返回

python調用Shell腳本,有兩種方法:os.system(command)os.popen(command), 前者返回值是腳本的退出狀態碼, 後者的返回值是腳本執行過程當中的輸出內容. 實際使用時視需求狀況而選擇.linux

# 經過 os.popen() 返回的是 file read 的對象,對其進行讀取 read() 的操做能夠看到執行的輸出。
output = os.popen('cat /proc/cpuinfo')
print(output.read())

系統信息

  • os.name
  • os.uname()
  • sys.platform(import sys)
  • os.sep
  • os.linesep
  • os.pathsep
  • os.curdir
  • os.pardir
  • os.cpu.count()
# 獲取系統類型
>>> os.name
'posix'
>>> os.uname()
posix.uname_result(sysname='Linux', nodename='lart', release='4.15.0-43-generic', version='#46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018', machine='x86_64')
>>> os.uname()[0]
'Linux'
>>> os.uname()[4]
'x86_64'
>>> import sys
>>> sys.platform
'linux'

# 獲取當前路徑/父路徑的標識符
>>> os.curdir
'.'
>>> os.pardir
'..'
# 獲取路徑分隔符和換行符的表示
>>> os.sep
'/'
>>> os.linesep
'\n'
# 獲取當前系統環境變量分隔符
>>> os.pathsep
':'

# 獲取cpu核心數
# 此數字不等於當前進程可使用的CPU數量。可使用`len(os.sched_getaffinity(0))`得到可用CPU的數量
>>> os.cpu_count()
12
>>> len(os.sched_getaffinity(0))
12

文件(夾)操做

  • os.remove(path, *, dir_fd=None)
    • 移除path對應的 文件
    • 若path爲文件夾, 會拋出異常OSError
  • os.rmdir(path, *, dir_fd=None)
    • 移除path對應的 文件夾
    • Only works when the directory is empty, otherwise, OSError is raised.
  • os.mkdir(path, mode=0o777, *, dir_fd=None)
    • 建立path對應的 文件夾
    • If the directory already exists, FileExistsError is raised.
  • os.removedirs(name)
    • 遞歸刪除文件夾
    • For example, os.removedirs('foo/bar/baz') will first remove the directory 'foo/bar/baz', and then remove 'foo/bar' and 'foo' if they are empty. Raises OSError if the leaf directory could not be successfully removed
  • os.makedirs(name, mode=0o777, exist_ok=False)
    • 遞歸建立文件夾
    • If exist_ok is False (the default), an OSError is raised if the target directory already exists.
    • Note makedirs() will become confused if the path elements to create include pardir (eg. 「..」 on UNIX systems).
  • os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
    • 將文件(夾)的名字從src改成dst
    • 只能對相應的文件進行重命名, 不能重命名文件的上級目錄名
    • If dst is a directory, OSError will be raised. 若是src參數對應文件或目錄不存在, 以及若是dst參數對應文件或目錄已經存在,都會報錯
    • If you want cross-platform overwriting of the destination, use replace().
  • os.renames(old, new)
    • 遞歸重命名文件(文件夾)
    • 既能夠重命名文件, 也能夠重命名文件的上級目錄名
    • Note This function can fail with the new directory structure made if you lack permissions needed to remove the leaf directory or file.

路徑獲取

  • os.getcwd()
  • os.listdir(path='.')
  • os.scandir(path='.')
  • os.walk(top, topdown=True, onerror=None, followlinks=False)
######################################################################################
# 返回當前進程工做路徑
>>> os.getcwd()
'/home/lart/md/python總結'

######################################################################################
# 返回指定path下的文件夾與文件(包含後綴名)的完整名字, 不包含'.', '..'這樣的特殊目錄
>>> os.listdir('.')
['converter.py', 'face++.py', 'Face++.ipynb', 'person-young-man-beard-emotions-157966.png', '.ipynb_checkpoints', '.idea', 'supervisely.py', 'facepp-python-sdk-master']

######################################################################################
# 使用內容管理器管理os.scandir迭代器, 返回的是一個`os.DirEntry`對象, 相比`os.listdir`能夠得到更多的信息
# `os.DirEntry` Object yielded by scandir() to expose the file path and other file attributes of a directory entry.
# 包含以下屬性與方法: `name, path, inode(), is_dir(*, follow_symlinks=True), is_file(*, follow_symlinks=True), is_symlink(), stat(*, follow_symlinks=True)`
>>> with os.scandir('.') as it:
...     for entry in it:
...         if not entry.name.startswith('.') and entry.is_file():
...             print(entry.name)
...         if entry.is_dir():
...             print(f"{entry.name}是名字")
...
converter.py
face++.py
Face++.ipynb
person-young-man-beard-emotions-157966.png
.ipynb_checkpoints是名字
.idea是名字
supervisely.py
facepp-python-sdk-master是名字

有目錄:git

➜  tool_scripts tree
.
├── converter.py
├── Face++.ipynb
├── facepp-python-sdk-master
│   ├── call_four_task.ipynb
│   ├── call.py
│   ├── facepp_custom.py
│   ├── imgResource
│   │   ├── demo.jpeg
│   │   ├── gray_image.png
│   │   ├── merge.jpg
│   │   ├── resultImg.jpg
│   │   ├── resultImg.png
│   │   ├── search.png
│   │   ├── segment.b64
│   │   └── segment.jpg
│   ├── PythonSDK
│   │   ├── compat.py
│   │   ├── facepp.py
│   │   ├── ImagePro.py
│   │   ├── __pycache__
│   │   │   ├── compat.cpython-36.pyc
│   │   │   ├── facepp.cpython-36.pyc
│   │   │   ├── ImagePro.cpython-36.pyc
│   │   │   └── structures.cpython-36.pyc
│   │   └── structures.py
│   ├── Python SDK demo 使用文檔.pdf
│   └── README.md
├── face++.py
├── person-young-man-beard-emotions-157966.png
└── supervisely.py

4 directories, 26 files
######################################################################################
# os.walk(top, topdown=True, onerror=None, followlinks=False)
# top 是要便利的目錄的地址, 爲最上層的地址
# topdown 爲True(默認爲True),則優先遍歷父目錄(先把父目錄裏的全部文件(文件夾)遍歷完, 在搜索子文件夾),不然優先遍歷top的子目錄 (廣度優先與深度優先)
# onerror 須要一個callable對象,當walk須要異常時,會調用
# followlinks若是爲True,則會遍歷目錄下的快捷方式(linux下是`symbolic link`)實際所指的目錄(默認False)
#
# os.walk 的返回值是一個生成器(generator),也就是說不斷的遍歷它,來得到全部的內容。
# 每次遍歷的對象都是返回的是一個三元組`(dirpath, dirnames, filenames)`
# dirpath (string)當前正在遍歷的這個文件夾的自己的地址
# dirnames (list)**該文件夾中** 全部的 *子文件夾* 的名字(不包括子目錄, excluding '.' and '..')
# filenames (list)**該文件夾中** 全部的 *文件* 的名字
# 注意:
#   - 名字列表中不包含完整路徑, 要想獲得完整的路徑, 可使用`os.path.join(dirpath, name)`.
#   - 當設定`followlinks`爲True時, 如果連接指向父文件夾, 會致使無線遞歸, 由於`.walk()`不會關注搜索過得部分
#   - 若是傳遞相對路徑名,請不要在`walk()`的恢復之間更改當前工做目. `walk()`從不更改當前目錄, 並假定其調用者也不會

###############################################################################
# 下面使用了`topdown=True`
>>> for dirpath, dirnames, filenames in os.walk('.'):
...     print(dirpath)
...     print(dirnames)
...     print(filenames)
...
.
['.ipynb_checkpoints', '.idea', 'facepp-python-sdk-master']
['converter.py', 'face++.py', 'Face++.ipynb', 'person-young-man-beard-emotions-157966.png', 'supervisely.py']
./.ipynb_checkpoints
[]
['Face++-checkpoint.ipynb']
./.idea
[]
['misc.xml', 'modules.xml', 'workspace.xml', 'tool_scripts.iml', 'encodings.xml']
./facepp-python-sdk-master
['imgResource', 'PythonSDK', '.ipynb_checkpoints', '.idea']
['call.py', 'facepp_custom.py', 'call_four_task.ipynb', 'Python SDK demo 使用文檔.pdf', 'README.md', '.gitignore']
./facepp-python-sdk-master/imgResource
[]
['demo.jpeg', 'resultImg.jpg', 'merge.jpg', 'gray_image.png', 'segment.jpg', 'search.png', 'segment.b64', 'resultImg.png']
./facepp-python-sdk-master/PythonSDK
['__pycache__']
['compat.py', 'facepp.py', 'ImagePro.py', 'structures.py']
./facepp-python-sdk-master/PythonSDK/__pycache__
[]
['compat.cpython-36.pyc', 'facepp.cpython-36.pyc', 'ImagePro.cpython-36.pyc', 'structures.cpython-36.pyc']
./facepp-python-sdk-master/.ipynb_checkpoints
[]
['call_four_task-checkpoint.ipynb']
./facepp-python-sdk-master/.idea
[]
['misc.xml', 'modules.xml', 'facepp-python-sdk-master.iml', 'workspace.xml', 'encodings.xml']

###############################################################################
# 下面使用了`topdown=False`
>>> for dirpath, dirnames, filenames in os.walk('.', topdown=False):
...     print(dirpath)
...     print(dirnames)
...     print(filenames)
...
./.ipynb_checkpoints
[]
['Face++-checkpoint.ipynb']
./.idea
[]
['misc.xml', 'modules.xml', 'workspace.xml', 'tool_scripts.iml', 'encodings.xml']
./facepp-python-sdk-master/imgResource
[]
['demo.jpeg', 'resultImg.jpg', 'merge.jpg', 'gray_image.png', 'segment.jpg', 'search.png', 'segment.b64', 'resultImg.png']
./facepp-python-sdk-master/PythonSDK/__pycache__
[]
['compat.cpython-36.pyc', 'facepp.cpython-36.pyc', 'ImagePro.cpython-36.pyc', 'structures.cpython-36.pyc']
./facepp-python-sdk-master/PythonSDK
['__pycache__']
['compat.py', 'facepp.py', 'ImagePro.py', 'structures.py']
./facepp-python-sdk-master/.ipynb_checkpoints
[]
['call_four_task-checkpoint.ipynb']
./facepp-python-sdk-master/.idea
[]
['misc.xml', 'modules.xml', 'facepp-python-sdk-master.iml', 'workspace.xml', 'encodings.xml']
./facepp-python-sdk-master
['imgResource', 'PythonSDK', '.ipynb_checkpoints', '.idea']
['call.py', 'facepp_custom.py', 'call_four_task.ipynb', 'Python SDK demo 使用文檔.pdf', 'README.md', '.gitignore']
.
['.ipynb_checkpoints', '.idea', 'facepp-python-sdk-master']
['converter.py', 'face++.py', 'Face++.ipynb', 'person-young-man-beard-emotions-157966.png', 'supervisely.py']

os.path

路徑顯示

  • os.path.abspath(path)
    • 返回path對應的絕對路徑
  • os.path.commonpath(paths)
  • os.path.commonprefix(list)
>>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
'/usr/l'
>>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
'/usr'
  • os.path.dirname(path)
    • 返回path對應的倒數第二級目錄
>>> path = '/home/lart/Datasets/tool_scripts'
>>> os.path.dirname(path)
'/home/lart/Datasets'
>>> path = '/home/lart/Datasets/tool_scripts/converter.py'
>>> os.path.dirname(path)
'/home/lart/Datasets/tool_scripts'
  • os.path.exists(path)
'/home/lart/Datasets'
>>> os.path.exists(path)
True
>>> path = '/home/lart/Datasets/tool_scripts/converter.py'
>>> os.path.exists(path)
True

路徑判斷

  • os.path.expanduser(path)
    • 替換path中的~爲用戶目錄(HOME)實際值
  • os.path.expandvars(path)
    • 替換$name or ${name}爲environment variable name對應的實際值
>>> path = '~/Datasets/tool_scripts/converter.py'
>>> os.path.expanduser(path)
'/home/lart/Datasets/tool_scripts/converter.py'
>>> path = '~/Datasets/tool_scripts'
>>> os.path.expanduser(path)
'/home/lart/Datasets/tool_scripts'

路徑時間

  • os.path.getatime(path)
    • 返回最後一次訪問path的時間
  • os.path.getmtime(path)
    • 返回最後一次修改path的時間
  • os.path.getctime(path)
    • 返回path對應的的ctime
    • 在某些系統(如Unix)上是最後一次元數據更改的時間,而在其餘系統(如Windows)上則是路徑的建立時間
>>> path = '/home/lart/Datasets/tool_scripts'
>>> os.path.getctime(path)
1547694633.120985
>>> os.path.getctime(path + '/converter.py')
1546766886.501085

路徑體積

  • os.path.getsize(path)
    • 返回path對應的體積
>>> path = '/home/lart/Datasets/tool_scripts'
>>> os.path.getsize(path)
4096
>>> os.path.getsize(path + '/converter.py')
857

路徑規範

  • os.path.isabs(path)
    • path是否爲絕對路徑
  • os.path.isfile(path)
  • os.path.isdir(path)
  • os.path.islink(path)
    • 如名
  • os.path.join(path, *paths)
    • 使用系統對應的分隔符拼接路徑
    • 對於Windows: Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.
  • os.path.normcase(path)
    • 規範化路徑名的大小寫。
    • 在Unix和Mac OS X上,這將返回路徑不變; 在不區分大小寫的文件系統上,它將路徑轉換爲小寫。在Windows上,它還將正斜槓轉換爲反斜槓
  • os.path.normpath(path)
    • 經過摺疊冗餘分隔符和上級引用來規範化路徑名,以便A//BA/B/A/./BA/foo/../B都變爲A/B.
    • 此字符串操做可能會更改包含符號連接的路徑的含義
    • 在Windows上,它將正斜槓轉換爲反斜槓
    • 要規範化大小寫,請使用normcase()
  • os.path.realpath(path)
    • 返回指定文件名的規範路徑,消除路徑中遇到的任何符號連接(若是操做系統支持它們)
  • os.path.samefile(path1, path2)
    • 若是兩個路徑名參數都引用相同的文件或目錄,則返回True
  • os.path.sameopenfile(fp1, fp2)
    • 若是文件描述符fp1和fp2引用同一文件,則返回True
  • os.path.split(path)
    • 將路徑名路徑拆分爲一對(head, tail),其中tail是最後一個路徑名組件,head是指向該路徑的全部內容, tail永遠不會有斜線; 若是path以斜線結尾,則tail將爲空; 若是路徑中沒有斜槓,則head將爲空
    • 若是path爲空,則head和tail都爲空
    • 尾部斜槓從head剝離,除非它是root(僅一個或多個斜槓)
    • 在全部狀況下,join(head, tail)返回與path相同位置的路徑(但字符串可能不一樣).
  • os.path.splitdrive(path)
    • 將路徑名路徑拆分爲一對(drive, tail),其中drive是掛載點或空字符串. 在不使用驅動器規格的系統上,drive將始終爲空字符串
    • 在全部狀況下,drive + tail將與path相同。
  • os.path.splitext(path)
    • 將路徑名路徑拆分爲一對(root, ext), 使得root + ext == path,ext爲空或以.開頭,最多包含一個句點. basename的前導.被忽略
    • splitext('.cshrc')返回('.cshrc','')
  • os.path.supports_unicode_filenames
    • 若是能夠將任意Unicode字符串用做文件名(在文件系統強加的限制內),則爲True。

glob

glob模塊根據Unix shell使用的規則查找與指定模式匹配的全部路徑名,儘管結果以任意順序返回。正則表達式

實現了:shell

  • * 表示匹配0到多個字符
  • 表示匹配一個字符
  • [] 表示匹配括號裏表示的字符範圍
    • [exp] 匹配指定範圍內的字符,如:[1-9]匹配1至9範圍內的字符, 破折號(-)表示一個範圍, 上面的範圍也可直接用[0123456789]來表示
    • [!exp] 匹配不在指定範圍內的字符
    • 對於文字匹配,將元字符包裝在括號中。例如,'[?]'匹配字符'?'

glob中模式規則不是正則表達式, 而是, 符合標準Uinx路徑擴展規則. 可是Shell變量名和符號(~)是不被擴充的, 只有一些特殊的字符: 兩個不一樣的通配符和字母範圍被支持(見上). 對於~符和shell變量擴展,請使用os.path.expanduser()os.path.expandvars(0). 模塊規則適合於文檔名的片斷(以/為分隔, 也就是隻能匹配//之間的文本), 但模式中的路徑能夠是相對或者絕對路徑.ide

這是經過一致地使用os.scandir()fnmatch.fnmatch()函數來完成的,而不是經過實際調用子shell。請注意,與fnmatch.fnmatch()不一樣,glob將以點(.)開頭的文件名視爲特殊狀況, 通配符不會進行匹配. 可見後面的例子.函數

  • glob.glob(pathname, *, recursive=False)
    • 返回可能爲空的(無序的, 能夠藉助sorted()排序)匹配路徑名字列表, 這個pathname必須是包含路徑規範的字符串
    • 若是recursivetrue,則模式**匹配任何文件以及零個或多個目錄和子目錄, 若是模式後跟os.sep,則只有目錄和子目錄匹配
    • 注意在大型目錄樹中使用**模式可能會消耗過多的時間。
  • glob.iglob(pathname, *, recursive=False)
    • 功能同上, 只是返回一個迭代器, 避免了同時的大量存儲
>>> import glob
>>> path
'/home/lart/Datasets/tool_scripts'
>>> glob.iglob(path + '/*')
<generator object _iglob at 0x7fdca3773930>
# 這裏只返回下一級
>>> glob.glob(path + '/*', recursive=True)
['/home/lart/Datasets/tool_scripts/converter.py', '/home/lart/Datasets/tool_scripts/face++.py', '/home/lart/Datasets/tool_scripts/Face++.ipynb', '/home/lart/Datasets/tool_scripts/person-young-man-beard-emotions-157966.png', '/home/lart/Datasets/tool_scripts/supervisely.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master']
# 這裏會遍歷全部的子目錄和文件
>>> glob.glob(path + '/**', recursive=True)
['/home/lart/Datasets/tool_scripts/', '/home/lart/Datasets/tool_scripts/converter.py', '/home/lart/Datasets/tool_scripts/face++.py', '/home/lart/Datasets/tool_scripts/Face++.ipynb', '/home/lart/Datasets/tool_scripts/person-young-man-beard-emotions-157966.png', '/home/lart/Datasets/tool_scripts/supervisely.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/call.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/demo.jpeg', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/resultImg.jpg', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/merge.jpg', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/gray_image.png', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/segment.jpg', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/search.png', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/segment.b64', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/imgResource/resultImg.png', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/compat.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/facepp.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/__pycache__', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/__pycache__/compat.cpython-36.pyc', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/__pycache__/facepp.cpython-36.pyc', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/__pycache__/ImagePro.cpython-36.pyc', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/__pycache__/structures.cpython-36.pyc', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/ImagePro.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/PythonSDK/structures.py', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/facepp_custom.py','/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/call_four_task.ipynb', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/Python SDK demo 使用文檔.pdf', '/home/lart/Datasets/tool_scripts/facepp-python-sdk-master/README.md']


>>> 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/']

If the directory contains files starting with . they won’t be matched by default. 須要在匹配路徑名字上補上符號.測試

For example, consider a directory containing card.gif and .card.gif:

>>>
>>> import glob
>>> glob.glob('*.gif')
['card.gif']
>>> glob.glob('.c*')
['.card.gif']
  • glob.escape(pathname)
    • 轉義全部的特殊字符('?','*'和'['])
    • 若是想匹配任意可能包含特殊字符的字符串,這將很是有用。drive/UNC的sharepoints中的特殊字符不會轉義,例如在Windows系統上escape('//?/c:/Quo vadis?.txt')將返回'//?/c:/Quo vadis[?].txt'.
    • 每個特殊字符通過構建包含單個條目的字符範圍來轉義, 例如,[?]即是字符?的轉義
# https://hk.saowen.com/a/83de58e8a7e060d8ace69c912cbd209948d6c4fe533aa2746201d96a1b45a8bf
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()

# 輸出
Searching for:  'dir/*[?].txt'
dir/file?.txt

Searching for:  'dir/*[*].txt'
dir/file*.txt

Searching for:  'dir/*[[].txt'
dir/file[.txt
# https://www.jianshu.com/p/b1f24d56d73b
>>> glob.escape('./**.?.*.[a-z]')
'./[*][*].[?].[*].[[]a-z]'

fnmatch

此模塊提供對Unix shell樣式通配符的支持,這些通配符與正則表達式(在re模塊中記錄)不一樣。shell樣式通配符中使用的特殊字符是:

  • * 表示匹配0到多個字符
  • 表示匹配一個字符
  • [] 表示匹配括號裏表示的字符範圍
    • [exp] 匹配指定範圍內的字符,如:[1-9]匹配1至9範圍內的字符, 破折號(-)表示一個範圍, 上面的範圍也可直接用[0123456789]來表示
    • [!exp] 匹配不在指定範圍內的字符
    • 對於文字匹配,將元字符包裝在括號中。例如,'[?]'匹配字符'?'

請注意:

  • 文件名分隔符(Unix上的/)對於此模塊並非特殊字符。與glob模塊略有不一樣
  • 一樣,以.開頭的文件名對於此模塊並非特殊字符,而且可用*?匹配

主要的方法:

  • fnmatch.fnmatch(filename, pattern)
    • 測試是否filename字符串能夠匹配模式pattern, 返回True或False
    • 這兩個參數都使用os.path.normcase()進行大小寫規範化。fnmatchcase()可用於執行區分大小寫的比較,不管這是不是操做系統的標準。
  • fnmatch.fnmatchcase(filename, pattern)
    • 比較區分大小寫,不使用os.path.normcase()
  • fnmatch.filter(names, pattern)
    • 返回與pattern匹配的名稱列表的子集。它與[n for n in names if fnmatch(n, pattern)]相同,但實現更有效。
  • fnmatch.translate(pattern)
    • 返回轉換爲正則表達式的shell樣式模式,以便與re.match()一塊兒使用。

對於目錄:

>>> print(os.popen('tree -a -L 2').read())
.
├── converter.py
├── Face++.ipynb
├── facepp-python-sdk-master
│   ├── call_four_task.ipynb
│   ├── call.py
│   ├── facepp_custom.py
│   ├── .gitignore
│   ├── .idea
│   ├── imgResource
│   ├── .ipynb_checkpoints
│   ├── PythonSDK
│   ├── Python SDK demo 使用文檔.pdf
│   └── README.md
├── face++.py
├── .idea
│   ├── encodings.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── tool_scripts.iml
│   └── workspace.xml
├── .ipynb_checkpoints
│   └── Face++-checkpoint.ipynb
├── person-young-man-beard-emotions-157966.png
├── supervisely.py
└── .test

從下面的測試能夠看出來, 實際上, glob應該更爲經常使用一些, fnmatch模塊不會忽略.開頭的文件(夾), 這有時候會形成沒必要要的麻煩, 因大多數時候, 是不會須要搜索這些文件夾的.

>>> import fnmatch
>>> for file in os.listdir('.'):
...     if fnmatch.fnmatch(file, '*'):
...         print(file)
...
converter.py
face++.py
.test
Face++.ipynb
person-young-man-beard-emotions-157966.png
.ipynb_checkpoints
.idea
supervisely.py
facepp-python-sdk-master

>>> glob.glob('./*')
['./converter.py', './face++.py', './Face++.ipynb', './person-young-man-beard-emotions-157966.png', './supervisely.py', './facepp-python-sdk-master']
>>> import fnmatch, re
>>>
>>> regex = fnmatch.translate('*.txt')
>>> regex
'(?s:.*\\.txt)\\Z'
>>> reobj = re.compile(regex)
>>> reobj.match('foobar.txt')
<re.Match object; span=(0, 10), match='foobar.txt'>

參考連接

相關文章
相關標籤/搜索