Hello,

I am new to python and try to learn more about it. How can I copy or move all the sub-folders (folderA, folderB, folderC,...) from folder1 to folder2 (folder2 is already existed)?

I tried this Click Here for files and it worked. How can I use something similar to this for moving/copying folders?

# move files from one directory to another
# if files alrady exist there, they will be overwritten
# retains original file date/time
import os
import shutil
# make sure that these directories exist
dir_src = "C:\\Python25\\ATest1\\"
dir_dst = "C:\\Python25\\ATest2\\"
for file in os.listdir(dir_src):
print file # testing
src_file = os.path.join(dir_src, file)
dst_file = os.path.join(dir_dst, file)
shutil.move(src_file, dst_file) 

Any help is greatly appreciated. Thanks.

Recommended Answers

All 6 Replies

Have you tried using the wildcard '*' as in:

dir_src = "C:\\Python25\\ATest1\\*"

? I'm not a python expert, but I would think this should work. Worth a try in any case.

Thanks for the replies. shutil.copytree or shutil.move copies/moves the whole folder1 and all of its sub-folders into folder2. My objective is just copy/move only the sub-folders of folder1 (not folder1 itself) into folder2.

distutils.dir_util.copy_tree does exactly what I want, but it only works in Windows not in Android. I am looking for a solution that works on all platforms.

Here is the code of distutils.dir_util.copy_tree()

def copy_tree(src, dst, preserve_mode=1, preserve_times=1,
              preserve_symlinks=0, update=0, verbose=1, dry_run=0):
    """Copy an entire directory tree 'src' to a new location 'dst'.

    Both 'src' and 'dst' must be directory names.  If 'src' is not a
    directory, raise DistutilsFileError.  If 'dst' does not exist, it is
    created with 'mkpath()'.  The end result of the copy is that every
    file in 'src' is copied to 'dst', and directories under 'src' are
    recursively copied to 'dst'.  Return the list of files that were
    copied or might have been copied, using their output name.  The
    return value is unaffected by 'update' or 'dry_run': it is simply
    the list of all files under 'src', with the names changed to be
    under 'dst'.

    'preserve_mode' and 'preserve_times' are the same as for
    'copy_file'; note that they only apply to regular files, not to
    directories.  If 'preserve_symlinks' is true, symlinks will be
    copied as symlinks (on platforms that support them!); otherwise
    (the default), the destination of the symlink will be copied.
    'update' and 'verbose' are the same as for 'copy_file'.
    """
    from distutils.file_util import copy_file

    if not dry_run and not os.path.isdir(src):
        raise DistutilsFileError, \
              "cannot copy tree '%s': not a directory" % src
    try:
        names = os.listdir(src)
    except os.error, (errno, errstr):
        if dry_run:
            names = []
        else:
            raise DistutilsFileError, \
                  "error listing files in '%s': %s" % (src, errstr)

    if not dry_run:
        mkpath(dst, verbose=verbose)

    outputs = []

    for n in names:
        src_name = os.path.join(src, n)
        dst_name = os.path.join(dst, n)

        if n.startswith('.nfs'):
            # skip NFS rename files
            continue

        if preserve_symlinks and os.path.islink(src_name):
            link_dest = os.readlink(src_name)
            if verbose >= 1:
                log.info("linking %s -> %s", dst_name, link_dest)
            if not dry_run:
                os.symlink(link_dest, dst_name)
            outputs.append(dst_name)

        elif os.path.isdir(src_name):
            outputs.extend(
                copy_tree(src_name, dst_name, preserve_mode,
                          preserve_times, preserve_symlinks, update,
                          verbose=verbose, dry_run=dry_run))
        else:
            copy_file(src_name, dst_name, preserve_mode,
                      preserve_times, update, verbose=verbose,
                      dry_run=dry_run)
            outputs.append(dst_name)

    return outputs

It looks like a simple recursive code which should work on all platforms. You can raise your own exception instead of DistutilsFileError. It only depends on 2 functions from the distutils package: mkpath() which creates a directory and its ancestors and copy_file() which copies a file. You could replace these 2 functions by your own code.

Many thanks to Gribouillis for your invaluable time. I just started to learn programming, so please bear with me. Please kindly provide a very simple code like in post#1 or below. No need to check for error or anything. All folders and sub-folders already exist. Folder1 has only sub-folders, not a combination of files and sub-folders. Just need to copy/move all sub-folders from folder1 into folder2 (without copy/move folder1 itself). I've tried the following:

  1. This one works as intended in Windows 7, not in Android:

    import distutils.core
    src = 'path/to/folder1'
    dst = 'path/to/folder2'

    try:
    distutils.dir_util.copy_tree(src, dst)
    except: pass

  2. This one works in both platforms, but it copies folder1 itself together with all its sub-folders:

    import shutil
    src = 'path/to/folder1'
    dst = 'path/to/folder2'

    def copy_folders():
    try:
    shutil.copytree(src, dst)
    except: pass
    copy_folders()

I just want the contents (sub-folders) of folder1 to be copied, but NOT folder1 itself. I also tried wildcard (src = 'path/to/folder1/*') but no go. shutil.move does not do anything in Android.
Android is the platform I really want the code to work.
I am all ears and thanks for all inputs.

"""
After extracting the RAR, we run this to move all the files into
the appropriate train/test folders.

Should only run this file once!
"""
import os
import os.path

def get_train_test_lists(version='01'):

# Get our files based on version.

test_file = os.path.join('traintestlist', 'testlist' + version + '.txt')
train_file = os.path.join('traintestlist', 'trainlist' + version + '.txt')

# Build the test list.
with open(test_file) as fin:
    test_list = [row.strip() for row in list(fin)]

# Build the train list. Extra step to remove the class index.
with open(train_file) as fin:
    train_list = [row.strip() for row in list(fin)]
    train_list = [row.split(' ')[0] for row in train_list]

# Set the groups in a dictionary.
file_groups = {
    'train': train_list,
    'test': test_list
}

return file_groups

def move_files(file_groups):

"""This assumes all of our files are currently in this directory. So move them to the appropriate spot. Only needs to happen once """

# Do each of our groups.
for group, videos in file_groups.items():

    # Do each of our videos.
    for video in videos:

        # Get the parts.
        parts = video.split(os.path.sep)
        classname = parts[0]
        filename = parts[0]

        # Check if this class exists.
        if not os.path.exists(os.path.join(group, classname)):
            print("Creating folder for %s/%s" % (group, classname))
            os.makedirs(os.path.join(group, classname))

        # Check if we have already moved this file, or at least that it
        # exists to move.
        if not os.path.exists(filename):
            print("Can't find %s to move. Skipping." % (filename))
            continue

        # Move it.
        dest = os.path.join(group, classname, filename)
        print("Moving %s to %s" % (filename, dest))
        os.rename(filename, dest)

print("Done.")

def main():
"""
Go through each of our train/test text files and move the videos
to the right place.
"""

Get the videos in groups so we can move them

group_lists = get_train_test_lists()

# Move the files.
move_files(group_lists)

if name == 'main':
main()

This code successfully create the folders and sub-folders regarding to the data. But it is not performing the move operation.

Any help is greatly appreciated. Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.