shutil.copytree without files

2019-04-04 16:10发布

问题:

I'm trying use shutil.copytree:

shutil.copytree(SOURCE_DIR, TARGET_DIR, ignore=None)

This copy also files in folder. I need copy only folders without ANY files. How to do it?

回答1:

You can do that by providing a "ignore" function

def ig_f(dir, files):
    return [f for f in files if os.path.isfile(os.path.join(dir, f))]

shutil.copytree(SRC, DES, ignore=ig_f)

Basically, when you call copytree, it will recursively go to each child folder and provide a list of files in that folder to the ignore function to check if those files are suitable based on a pattern. The ignored files will be returned as a list in the end of the function and then, copytree will only copy items excluding from that list (which in your case, contains all the files in the current folder)



回答2:

You should consider using os.walk.

Here is an example for os.walk. This way you could list all the directories and then create them with os.mkdir.



回答3:

use distutils.dir_util.create_tree to just copy directory structure (not files)

note : the argument files is a list of filenames. if you want something that would work as shutils.copytree:

import os
import distutils.dir_util
def copy_tree(source, dest, **kwargs):
    filenames = [os.path.join(path, file_) for path, _, files in os.walk(source) for file_ in files]
    distutils.dir_util.create_tree(dest, filenames, **kwargs)


回答4:

Here's an implementation of @Oz123's solution which is based on os.walk():

import os

def create_empty_dirtree(srcdir, dstdir, onerror=None):
    srcdir = os.path.abspath(srcdir)
    srcdir_prefix = len(srcdir) + len(os.path.sep)
    os.makedirs(dstdir)
    for root, dirs, files in os.walk(srcdir, onerror=onerror):
        for dirname in dirs:
            dirpath = os.path.join(dstdir, root[srcdir_prefix:], dirname)
            try:
                os.mkdir(dirpath)
            except OSError as e:
                if onerror is not None:
                    onerror(e)


回答5:

If you want ignore pattern functionality with os.walk(), then:

ignorePatterns=[".git"]
def create_empty_dirtree(src, dest, onerror=None):
    src = os.path.abspath(src)
    src_prefix = len(src) + len(os.path.sep)
    for root, dirs, files in os.walk(src, onerror=onerror):
        for pattern in ignorePatterns:
            if pattern in root:
                break
        else:
            #If the above break didn't work, this part will be executed
            for dirname in dirs:
                for pattern in ignorePatterns:
                    if pattern in dirname:
                        break
                else:
                    #If the above break didn't work, this part will be executed
                    dirpath = os.path.join(dest, root[src_prefix:], dirname)
                    try:
                        os.makedirs(dirpath,exist_ok=True)
                    except OSError as e:
                        if onerror is not None:
                            onerror(e)
                continue;#If the above else didn't executed, this will be reached

        continue;#If the above else didn't executed, this will be reached

This will ignore .git directory.

Note: This requires Python >=3.2 as I used the exist_ok option with makedirs which isn't available on older versions.



标签: python shutil