Use fnmatch.filter to filter files by more than one possible file extension

后端 未结 8 1802
面向向阳花
面向向阳花 2021-01-31 02:52

Given the following piece of python code:

for root, dirs, files in os.walk(directory):
    for filename in fnmatch.filter(files, \'*.png\'):
        pass
         


        
相关标签:
8条回答
  • 2021-01-31 03:06

    If you only need to check extensions (i.e. no further wildcards), why don't you simply use basic string operations?

    for root, dirs, files in os.walk(directory):
        for filename in files:
            if filename.endswith(('.jpg', '.jpeg', '.gif', '.png')):
                pass
    
    0 讨论(0)
  • 2021-01-31 03:06

    This isn't really elegant either, but it works:

    for root, dirs, files in os.walk(directory):
        for filename in fnmatch.filter(files, '*.png') + fnmatch.filter(files, '*.jpg') + fnmatch.filter(files, '*.jpeg') + fnmatch.filter(files, '*.gif'):
            pass
    
    0 讨论(0)
  • 2021-01-31 03:10

    Here is what I am using to filter files in apache log directories. Here I exclude errors flles

    rep_filters = [now.strftime("%Y%m%d")]
    def files_filter(liste_fic, filters = rep_filters):
        s = "(fic for fic in liste_fic if fic.find('error') < 0"
        for filter in filters:
            s += " and fic.find('%s') >=0 " % filter
        s += ")"
        return eval(s)
    
    0 讨论(0)
  • 2021-01-31 03:12

    Please try this:

    # pattern_list = ['*.jpg', '__.*']
    def checkFilepatter(filename, pattern_list):
        for pattern in pattern_list:
            if fnmatch.fnmatch(filename, pattern):
                return True
        return False
    
    0 讨论(0)
  • 2021-01-31 03:14

    I think your code is actually fine. If you want to touch every filename only once, define your own filtering function:

    def is_image_file(filename, extensions=['.jpg', '.jpeg', '.gif', '.png']):
        return any(filename.endswith(e) for e in extensions)
    
    for root, dirs, files in os.walk(directory):
        for filename in filter(is_image_file, files):
            pass
    
    0 讨论(0)
  • 2021-01-31 03:16

    I've been using this with a lot of success.

    import fnmatch
    import functools
    import itertools
    import os
    
    # Remove the annotations if you're not on Python3
    def find_files(dir_path: str=None, patterns: [str]=None) -> [str]:
        """
        Returns a generator yielding files matching the given patterns
        :type dir_path: str
        :type patterns: [str]
        :rtype : [str]
        :param dir_path: Directory to search for files/directories under. Defaults to current dir.
        :param patterns: Patterns of files to search for. Defaults to ["*"]. Example: ["*.json", "*.xml"]
        """
        path = dir_path or "."
        path_patterns = patterns or ["*"]
    
        for root_dir, dir_names, file_names in os.walk(path):
            filter_partial = functools.partial(fnmatch.filter, file_names)
    
            for file_name in itertools.chain(*map(filter_partial, path_patterns)):
                yield os.path.join(root_dir, file_name)
    

    Examples:

    for f in find_files(test_directory):
        print(f)
    

    yields:

    .\test.json
    .\test.xml
    .\test.ini
    .\test_helpers.py
    .\__init__.py
    

    Testing with multiple patterns:

    for f in find_files(test_directory, ["*.xml", "*.json", "*.ini"]):
        print(f)
    

    yields:

    .\test.json
    .\test.xml
    .\test.ini
    
    0 讨论(0)
提交回复
热议问题