How to use glob() to find files recursively?

前端 未结 28 1754
天涯浪人
天涯浪人 2020-11-21 22:54

This is what I have:

glob(os.path.join(\'src\',\'*.c\'))

but I want to search the subfolders of src. Something like this would work:

<
相关标签:
28条回答
  • 2020-11-21 23:08

    This is a working code on Python 2.7. As part of my devops work, I was required to write a script which would move the config files marked with live-appName.properties to appName.properties. There could be other extension files as well like live-appName.xml.

    Below is a working code for this, which finds the files in the given directories (nested level) and then renames (moves) it to the required filename

    def flipProperties(searchDir):
       print "Flipping properties to point to live DB"
       for root, dirnames, filenames in os.walk(searchDir):
          for filename in fnmatch.filter(filenames, 'live-*.*'):
            targetFileName = os.path.join(root, filename.split("live-")[1])
            print "File "+ os.path.join(root, filename) + "will be moved to " + targetFileName
            shutil.move(os.path.join(root, filename), targetFileName)
    

    This function is called from a main script

    flipProperties(searchDir)
    

    Hope this helps someone struggling with similar issues.

    0 讨论(0)
  • 2020-11-21 23:11

    For python >= 3.5 you can use **, recursive=True :

    import glob
    for x in glob.glob('path/**/*.c', recursive=True):
        print(x)
    

    Demo


    If recursive is True, the pattern ** will match any files and zero or more directories and subdirectories. If the pattern is followed by an os.sep, only directories and subdirectories match.

    0 讨论(0)
  • 2020-11-21 23:11

    Another way to do it using just the glob module. Just seed the rglob method with a starting base directory and a pattern to match and it will return a list of matching file names.

    import glob
    import os
    
    def _getDirs(base):
        return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]
    
    def rglob(base, pattern):
        list = []
        list.extend(glob.glob(os.path.join(base,pattern)))
        dirs = _getDirs(base)
        if len(dirs):
            for d in dirs:
                list.extend(rglob(os.path.join(base,d), pattern))
        return list
    
    0 讨论(0)
  • 2020-11-21 23:11
    import os, glob
    
    for each in glob.glob('path/**/*.c', recursive=True):
        print(f'Name with path: {each} \nName without path: {os.path.basename(each)}')
    
    • glob.glob('*.c') :matches all files ending in .c in current directory
    • glob.glob('*/*.c') :same as 1
    • glob.glob('**/*.c') :matches all files ending in .c in the immediate subdirectories only, but not in the current directory
    • glob.glob('*.c',recursive=True) :same as 1
    • glob.glob('*/*.c',recursive=True) :same as 3
    • glob.glob('**/*.c',recursive=True) :matches all files ending in .c in the current directory and in all subdirectories
    0 讨论(0)
  • 2020-11-21 23:13

    pathlib.Path.rglob

    Use pathlib.Path.rglob from the the pathlib module, which was introduced in Python 3.5.

    from pathlib import Path
    
    for path in Path('src').rglob('*.c'):
        print(path.name)
    

    If you don't want to use pathlib, use can use glob.glob('**/*.c'), but don't forget to pass in the recursive keyword parameter and it will use inordinate amount of time on large directories.

    For cases where matching files beginning with a dot (.); like files in the current directory or hidden files on Unix based system, use the os.walk solution below.

    os.walk

    For older Python versions, use os.walk to recursively walk a directory and fnmatch.filter to match against a simple expression:

    import fnmatch
    import os
    
    matches = []
    for root, dirnames, filenames in os.walk('src'):
        for filename in fnmatch.filter(filenames, '*.c'):
            matches.append(os.path.join(root, filename))
    
    0 讨论(0)
  • 2020-11-21 23:15
    import os
    import fnmatch
    
    
    def recursive_glob(treeroot, pattern):
        results = []
        for base, dirs, files in os.walk(treeroot):
            goodfiles = fnmatch.filter(files, pattern)
            results.extend(os.path.join(base, f) for f in goodfiles)
        return results
    

    fnmatch gives you exactly the same patterns as glob, so this is really an excellent replacement for glob.glob with very close semantics. An iterative version (e.g. a generator), IOW a replacement for glob.iglob, is a trivial adaptation (just yield the intermediate results as you go, instead of extending a single results list to return at the end).

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