Ignore case in glob() on Linux

前端 未结 6 775
星月不相逢
星月不相逢 2020-12-05 06:39

I\'m writing a script which will have to work on directories which are modified by hand by Windows and Linux users alike. The Windows users tend to not care at all about cas

相关标签:
6条回答
  • 2020-12-05 06:55

    Here is my non-recursive file search for Python with glob like behavior for Python 3.5+

    # Eg: find_files('~/Downloads', '*.Xls', ignore_case=True)
    def find_files(path: str, glob_pat: str, ignore_case: bool = False):
        rule = re.compile(fnmatch.translate(glob_pat), re.IGNORECASE) if ignore_case \
                else re.compile(fnmatch.translate(glob_pat))
        return [n for n in os.listdir(os.path.expanduser(path)) if rule.match(n)]
    

    Note: This version handles home directory expansion

    0 讨论(0)
  • 2020-12-05 06:58

    Use case-insensitive regexes instead of glob patterns. fnmatch.translate generates a regex from a glob pattern, so

    re.compile(fnmatch.translate(pattern), re.IGNORECASE)
    

    gives you a case-insensitive version of a glob pattern as a compiled RE.

    Keep in mind that, if the filesystem is hosted by a Linux box on a Unix-like filesystem, users will be able to create files foo, Foo and FOO in the same directory.

    0 讨论(0)
  • 2020-12-05 07:01

    Riffing off of @Timothy C. Quinn's answer, this modification allows the use of wildcards anywhere in the path. This is admittedly only case insensitive for the glob_pat argument.

    import re
    import os
    import fnmatch
    import glob
    
    def find_files(path: str, glob_pat: str, ignore_case: bool = False):
        rule = re.compile(fnmatch.translate(glob_pat), re.IGNORECASE) if ignore_case \
                else re.compile(fnmatch.translate(glob_pat))
        return [n for n in glob.glob(os.path.join(path, '*')) if rule.match(n)]
    
    0 讨论(0)
  • 2020-12-05 07:05

    You can replace each alphabetic character c with [cC], via

    import glob
    def insensitive_glob(pattern):
        def either(c):
            return '[%s%s]' % (c.lower(), c.upper()) if c.isalpha() else c
        return glob.glob(''.join(map(either, pattern)))
    
    0 讨论(0)
  • 2020-12-05 07:05

    Non recursively

    In order to retrieve the files (and files only) of a directory "path", with "globexpression":

    list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))]
    result = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]
    

    Recursively

    with walk:

    result = []
    for root, dirs, files in os.walk(path, topdown=True):
      result += [os.path.join(root, j) for j in files \
                 if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]
    

    Better also compile the regular expression, so instead of

    re.match(fnmatch.translate(globexpression)
    

    do (before the loop):

    reg_expr = re.compile(fnmatch.translate(globexpression), re.IGNORECASE)
    

    and then replace in the loop:

      result += [os.path.join(root, j) for j in files if re.match(reg_expr, j)]
    
    0 讨论(0)
  • 2020-12-05 07:16

    Depending on your case, you might use .lower() on both file pattern and results from folder listing and only then compare the pattern with the filename

    0 讨论(0)
提交回复
热议问题