How would you implement ant-shaped patterns in python to select groups of files?

Ant has a good way to select groups of files, it is most convenient to use ** to specify a directory tree. For instance.

**/CVS/*            # All files immediately under a CVS directory.
mydir/mysubdir/**   # All files recursively under mysubdir

Additional examples can be seen here:

http://ant.apache.org/manual/dirtasks.html

How would you implement this in python so that you can do something like:

files = get_files("**/CVS/*")
for file in files:
    print file

=>
CVS/Repository
mydir/mysubdir/CVS/Entries
mydir/mysubdir/foo/bar/CVS/Entries
+3
source share
6 answers

As soon as you come across **, you will have to rewrite the entire directory structure, so I think that at this moment the easiest method is to iterate through the directory using os.walk, build the path, and then check if it matches the pattern. You can probably convert to regex, for example:

def glob_to_regex(pat, dirsep=os.sep):
    dirsep = re.escape(dirsep)
    print re.escape(pat)
    regex = (re.escape(pat).replace("\\*\\*"+dirsep,".*")
                           .replace("\\*\\*",".*")
                           .replace("\\*","[^%s]*" % dirsep)
                           .replace("\\?","[^%s]" % dirsep))
    return re.compile(regex+"$")

( , , [a-z], , , ). ( \*\*/ , \*\*/CVS ./CVS, \*\* .)

, , , **, , . , , , , , :

  • . .. pat.split('/') -> ['**','CVS','*']

  • . . n levels deep -> look at pat[n].

  • pat[n] == '**' :

    • dirsep.join(pat[n:])
    • glob\_to\_regex()
    • os.walk , , . , .
  • pat "**", , /dirs, glob.glob(os.path.join(curpath,pat[n]))

  • pat "**", , , ( glob) pat[n]. , , ( pat[n+1])

+3

, OP. Python, - Formic, PyPI Cheeseshop. Formic :

import formic
fileset = formic.FileSet(include="**/CVS/*", default_excludes=False)
for file_name in fileset.qualified_files():
    print file_name

: default_excludes. Formic, Ant, CVS ( ), . default_excludes = False .

+4

os.walk - . Python (https://docs.python.org/2/library/os.html#os.walk) - .

"**/CVS/*" , , - :

def match(pattern, filename):
    if pattern.startswith("**"):
        return fnmatch.fnmatch(file, pattern[1:])
    else:
        return fnmatch.fnmatch(file, pattern)

fnmatch.fnmatch "*" ( ).

+2

. , , "os.walk". glob ' fnmatch ', .

0

os.walk - . .svn, , :

import re

for (dirpath, dirnames, filenames) in os.walk("."):
    if re.search(r'\.svn$', dirpath):
        for file in filenames:
            print file
0

Source: https://habr.com/ru/post/1697809/


All Articles