user2216451
user2216451

Reputation: 149

shutil.copytree without files

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?

Upvotes: 14

Views: 9999

Answers (6)

ajsp
ajsp

Reputation: 2670

The above answers work, but they certainly won't be hassle-free, and could easily cost you 30 minutes. If you're using Windows, the quickest method is to open the shell and use xcopy, i.e.:

c:\user> xcopy "source" "destination" /t /e

Alternatively, if you run Linux, you can use

rsync -a -f"+ */" -f"- *" source/ destination/

Upvotes: 0

Jahid
Jahid

Reputation: 22428

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.

Upvotes: 1

jfs
jfs

Reputation: 414235

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)

Upvotes: 2

thkang
thkang

Reputation: 11543

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)

Upvotes: 1

Thai Tran
Thai Tran

Reputation: 9935

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)

Upvotes: 21

oz123
oz123

Reputation: 28858

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.

Upvotes: 1

Related Questions