Filter directory using shutil.copytree?

Is there a way to filter a directory using an absolute path to it?

shutil.copytree(directory, target_dir, ignore = shutil.ignore_patterns("/Full/Path/To/aDir/Common")) 

This does not work when trying to filter the "Common" Directory located under " aDir ". If I do this:

 shutil.copytree(directory, target_dir, ignore = shutil.ignore_patterns("Common")) 

It works, but every directory named Common will be filtered out in this "tree", which is not what I want.

Any suggestions?

Thanks.

+7
source share
3 answers

You can make your own ignore function:

 shutil.copytree('/Full/Path', 'target', ignore=lambda directory, contents: ['Common'] if directory == '/Full/Path/To/aDir' else []) 

Or, if you want to be able to call copytree relative way:

 import os.path def ignorePath(path): def ignoref(directory, contents): return (f for f in contents if os.abspath(os.path.join(directory, f)) == path) return ignoref shutil.copytree('Path', 'target', ignore=ignorePath('/Full/Path/To/aDir/Common')) 

From the docs:

If the pointer is ignored, it must be callable, which will receive as its arguments the directory that copytree () is visiting, and a list of its contents returned by os.listdir (). Because copytree () is called recursively, the calling ignore call will be called once for each directory that is copied. The caller should return the sequence directory and file names relative to the current directory (that is, a subset of the elements in the second argument); these names will then be ignored during the copy process. ignore_patterns () can be used to create one called that ignores names based on glob style templates.

+10
source

The API for shutil.ignore_patterns () does not support absolute paths, but it is trivially easy to collapse your own option.

As a starting point, look at the source code for * ignore_patterns *:

 def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude files""" def _ignore_patterns(path, names): ignored_names = [] for pattern in patterns: ignored_names.extend(fnmatch.filter(names, pattern)) return set(ignored_names) return _ignore_patterns 

You can see that it returns a function that takes a path and a list of names, and returns a set of names to ignore. To support your use case, create your own similar function that takes advantage of the path argument. Pass your function to the ignore parameter in the copytree () call.

Alternatively, do not use shutal as-is. The source code is short and sweet, so it’s easy to cut, paste and customize.

+3
source

You want to create your own ignore function, which checks the current directory being processed and returns a list containing "Common" only if the parameter is / Full / Path / To / aDir.

 def ignore_full_path_common(dir, files): if dir == '/Full/Path/To/aDir': return ['Common'] return [] shutil.copytree(directory, target_dir, ignore=ignore_full_path_common) 
+3
source

All Articles