June 27, 2022

fnmatch Module in Python - File Name Pattern Matching

In this post we’ll see how to use functions in fnmatch module in Python which provides support for Unix shell-style wildcards. Note that Unix shell-style wildcards are not the same as regular expressions, the special characters used in shell-style wildcards are:

Pattern Meaning
* matches everything
? matches any single character
[seq] matches any character in seq
[!seq] matches any character not in seq

If you want to do literal matching, wrap the meta-characters in brackets. For example, '[?]' matches the character '?'.

Functions in Python fnmatch module

fnmatch module provides function to match files having specific pattern or filter files having specific pattern. These functions can be used if you want to search for files having some specific extension or searching file names with specific pattern.

1. fnmatch.fnmatch(filename, pattern)- This function tests whether the filename string matches the pattern string, returning a boolean True or False. In this function both parameters are case-normalized making it case insensitive.

Here is a Python example where we want to search log files created in December month of year 2020 i.e. we need to match files having pattern 2020-12-*.log

import os
import fnmatch


def search_files(path, pattern):
    print('Search pattern is', pattern)
    files = os.listdir(path)
    print('All Files:', files)
    for file in files:
        if fnmatch.fnmatch(file, pattern):
            print(file)


search_files("F:/knpcode/Python/Test", "2020-12-*.log")
Output
Search pattern is 2020-12-*.log
All Files: ['2020-11-20.log', '2020-12-20.log', '2020-12-21.log', 'newimage.png', 'Sub1', 'Sub2']
2020-12-20.log
2020-12-21.log

2. fnmatch.fnmatchcase(filename, pattern)- Similar to fnmatch.fnmatch but case-sensitive.

3. fnmatch.filter(names, pattern)- This function filters the list of names that match the pattern and returns the filtered subset of the list.

Here is a Python example where files having extension ‘.txt’ are filtered.

import os
import fnmatch


def filter_files(path, pattern):
    print('Search pattern is', pattern)
    files = os.listdir(path)
    print('All Files:', files)
    filtered_files = fnmatch.filter(files, pattern)
    print('Filtered Files:', filtered_files)


filter_files("F:/knpcode/Python/Test", "*.txt")
Output
Search pattern is *.txt
All Files: ['2020-11-20.log', '2020-12-20.log', '2020-12-21.log', 'abc.txt', 'newimage.png', 'Sub1', 'Sub2', 'test.txt']
Filtered Files: ['abc.txt', 'test.txt']

4. fnmatch.translate(pattern)- This function converts the shell-style pattern to a regular expression for using with re.match().

import fnmatch
import re


def filter_files(pattern):
    print('Search pattern is', pattern)
    regex = fnmatch.translate(pattern)
    print('Converted regex is', regex)
    reobj = re.compile(regex)
    print(reobj.match('test.txt'))
    print(reobj.match('test.log'))


filter_files("*.txt")
Output
Search pattern is *.txt
Converted regex is (?s:.*\.txt)\Z
<re.Match object; span=(0, 8), match='test.txt'>
None

That's all for the topic fnmatch Module in Python - File Name Pattern Matching. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment