glob
glob.glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False) list · Updated March 13, 2026 · Modules The glob module finds pathnames using pattern matching rules similar to the Unix shell. It handles *, ?, and character ranges with [] without invoking a subprocess. The module works by combining os.scandir() and fnmatch.fnmatch() internally.
Note that pathnames are returned in no particular order. If you need sorted results, sort them yourself. Files beginning with a dot are only matched by patterns that also start with a dot.
Functions Overview
| Function | Purpose |
|---|---|
glob() | Returns a list of pathnames matching a pattern |
iglob() | Returns an iterator of pathnames (memory efficient) |
escape() | Escapes special characters for literal matching |
translate() | Converts glob pattern to regular expression |
glob()
Returns a possibly empty list of path names that match the given pathname pattern.
glob.glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False)
Returns: list — A list of matching path strings (possibly empty)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pathname | str | — | A path specification with optional shell-style wildcards |
root_dir | str or path-like | None | Directory to search within (affects relative paths in results) |
dir_fd | int | None | File descriptor for root directory |
recursive | bool | False | If True, ** matches any number of directories |
include_hidden | bool | False | If True, ** matches hidden directories |
Examples
Basic wildcard matching
import glob
# Match all .txt files in current directory
result = glob.glob('*.txt')
print(result)
# ['file1.txt', 'file2.txt', 'notes.txt']
# Match files starting with 'test' and any extension
result = glob.glob('test*.*')
print(result)
# ['test1.py', 'test2.py', 'test_script.sh']
# Match single character wildcards
result = glob.glob('?.log')
print(result)
# ['a.log', 'b.log']
Character range matching
import glob
# Match files with single digit in name
result = glob.glob('[0-9]*.txt')
print(result)
# ['1.txt', '2.txt', '9a.txt']
# Match specific letters
result = glob.glob('[abc]*.py')
print(result)
# ['a.py', 'b.py', 'app.py']
# Negate ranges with [!...]
result = glob.glob('[!a]*.txt')
print(result)
# ['b.txt', 'c.txt']
Recursive directory searching
import glob
# Find all .py files in all subdirectories
result = glob.glob('**/*.py', recursive=True)
print(result)
# ['main.py', 'utils/helpers.py', 'tests/test_main.py']
# Search from a specific root directory
result = glob.glob('src/**/*.js', root_dir='/project', recursive=True)
print(result)
# ['src/app.js', 'src/components/Button.js']
Working with hidden files
import glob
# Include hidden files with **
result = glob.glob('**/*', recursive=True, include_hidden=True)
print(result)
# ['.hidden', 'file.txt', 'subdir/.secret']
# Match dotfiles explicitly
result = glob.glob('.config/*')
print(result)
# ['.config/app.yml', '.config/secrets']
iglob()
Returns an iterator that yields the same values as glob() without storing them all in memory. This is useful for processing large directory trees.
glob.iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False)
Returns: iterator — An iterator of path strings
Parameters
Same as glob().
Examples
Memory-efficient directory walking
import glob
# Process large directory without loading all paths into memory
for filepath in glob.iglob('**/*.log', recursive=True):
print(f"Processing: {filepath}")
# Processing: app.log
# Processing: logs/2024/error.log
# ...
# Combine with other iterators
py_files = list(glob.iglob('**/*.py', recursive=True))
java_files = list(glob.iglob('**/*.java', recursive=True))
all_code = py_files + java_files
Early termination
import glob
# Find first matching file without scanning everything
first_match = next(glob.iglob('**/config.yaml', recursive=True), None)
print(first_match)
# 'app/config.yaml' (or None if not found)
# Get exactly 5 results
import itertools
first_five = list(itertools.islice(glob.iglob('*.*'), 5))
print(first_five)
escape()
Escapes special shell characters (?, *, and [) in a pathname for literal matching. Useful when you need to match a filename that actually contains these characters.
glob.escape(pathname)
Returns: str — The escaped pathname
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pathname | str | — | Path to escape |
Examples
Matching literal filenames with special characters
import glob
# File actually named 'question?.txt'
filename = 'question?.txt'
escaped = glob.escape(filename)
print(escaped)
# 'question[?].txt'
# Now we can find it
result = glob.glob(escaped)
print(result)
# ['question?.txt']
Safe user input handling
import glob
def find_exact_file(user_input):
"""Safely find a file when user provides exact name."""
escaped = glob.escape(user_input)
return glob.glob(escaped)
# Even if user types '*.txt', we look for literal '*.txt'
result = find_exact_file('*.txt')
print(result)
# ['*.txt'] (if that file exists)
translate()
Converts a glob pattern to a regular expression string. This is useful when you need more control or want to use the pattern with the re module.
glob.translate(pathname, *, recursive=False, include_hidden=False, seps=None)
Returns: str — A regular expression pattern
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pathname | str | — | Glob pattern to convert |
recursive | bool | False | If True, ** matches multiple path segments |
include_hidden | bool | False | If True, wildcards can match dotfiles |
seps | str | None | Path separators to use |
Examples
Converting patterns to regex
import glob
import re
# Simple pattern conversion
pattern = glob.translate('*.txt')
print(pattern)
# '(?s:[^/]*\\.txt)\\z'
# Use with re module
regex = re.compile(glob.translate('test*.py'))
files = ['test1.py', 'test2.py', 'app.py']
matches = [f for f in files if regex.match(f)]
print(matches)
# ['test1.py', 'test2.py']
# Recursive pattern
pattern = glob.translate('**/*.txt', recursive=True)
print(pattern)
# '(?s:(?:.+/)?[^/]*\\.txt)\\z'
Common Patterns
Finding all files of a specific type
import glob
import os
# Get all images in current directory
images = []
for ext in ['*.jpg', '*.jpeg', '*.png', '*.gif']:
images.extend(glob.glob(ext))
# Or more elegantly with multiple extensions
images = glob.glob('*.[jp][pn][g]')
Building file lists for processing
import glob
def find_project_files(root='.'):
"""Find all source files in a project."""
patterns = [
'**/*.py',
'**/*.js',
'**/*.ts',
]
files = []
for pattern in patterns:
files.extend(glob.glob(f'{root}/{pattern}', recursive=True))
return sorted(set(files))
# Usage
for file in find_project_files('/myproject'):
print(file)
Excluding directories
import glob
# Find Python files but exclude test directories
all_py = glob.glob('**/*.py', recursive=True)
test_dirs = glob.glob('**/test*', recursive=True)
source_files = [f for f in all_py if not any(t in f for t in test_dirs)]
Platform-safe path handling
import glob
import os
# Use os.sep for cross-platform patterns
pattern = f'**{os.sep}*.txt'
result = glob.glob(pattern, recursive=True)
Errors
OSError
Raised when root_dir or dir_fd points to a non-existent directory.
import glob
try:
result = glob.glob('*.txt', root_dir='/nonexistent/path')
except OSError as e:
print(f"Error: {e}")
# Error: [Errno 2] No such file or directory: '/nonexistent/path'
ValueError
Raised when dir_fd is not a valid file descriptor.