user277465
user277465

Reputation:

recursive file copying into subdirectory

I need to copy all the files and folders to the current folder to a subdirectory. What would be the best way to do so? I tried the following snippet but it fails as it fails if the destination directory already exists.

def copy(d=os.path.curdir):
    dest = "t"
    for i in os.listdir(d):
        if os.path.isdir(i):
            shutil.copytree(i, dest)
        else:
            shutil.copy(i, dest)

I have the feeling that the same task can be done in a better and easier manner. How do i do it?

Upvotes: 3

Views: 5157

Answers (5)

fho
fho

Reputation: 500

Here is my version of a recursive copy method for python, seems to work :)

def copy_all(fr, to, overwrite=True):
  fr = os.path.normpath(fr)
  to = os.path.normpath(to)

  if os.path.isdir(fr):
    if (not os.path.exists(to + os.path.basename(fr)) and not
    os.path.basename(fr) == os.path.basename(to)):
      to += "/" + os.path.basename(fr)
      mkdirs(to)
    for file in os.listdir(fr):
      copy_all(fr + "/" + file, to + "/")
  else: #symlink or file
    dest = to
    if os.path.isdir(to):
      dest += "/"
      dest += os.path.basename(fr)

    if overwrite and (os.path.exists(dest) or os.path.islink(dest)
      rm(dest)

    if os.path.isfile(fr):
      shutil.copy2(fr, dest)
    else: #has to be a symlink
      os.symlink(os.readlink(fr), dest)  


def mkdirs(path):                                                 
  if not os.path.isdir(path):
    os.makedirs(path)


def rm(path):                                                     
  if os.path.isfile(path) or os.path.islink(path):
    os.remove(path)
  elif os.path.isdir(path):
    for file in os.listdir(path):
      fullpath = path+"/"+file
      os.rmdir(fullpath)

Upvotes: 0

Juan Carlos Moreno
Juan Carlos Moreno

Reputation: 2784

To extend mamnun's answer,

If you want to use the direct call to the os, I'd advise using cp -r since you seem to want a recursive copy for directories.

Upvotes: 1

khachik
khachik

Reputation: 28693

I would never do it on python, but the following solution came to mind. It doesn't look simple, but it should work and can be simplified (haven't checked, sorry, no access to the computer now):

def copyDirectoryTree(directory, destination, preserveSymlinks=True):
  for entry in os.listdir(directory):
    entryPath = os.path.join(directory, entry)
    if os.path.isdir(entryPath):
      entrydest = os.path.join(destination, entry)
      if os.path.exists(entrydest):
        if not os.path.isdir(entrydest):
          raise IOError("Failed to copy thee, the destination for the `" + entryPath + "' directory exists and is not a directory")
        copyDirectoryTree(entrypath, entrydest, preserveSymlinks)
      else:
        shutil.copytree(entrypath, entrydest, preserveSymlinks)
    else: #symlinks and files
      if preserveSymlinks:
        shutil.copy(entryPath, directory)
      else:
        shutil.copy(os.path.realpath(entryPath), directory)

Upvotes: 2

Max
Max

Reputation: 3429

Do you really need to use python? Because shutil functions cannot copy all file metadata and group permissions. Why don't you try built-in OS commands like cp in linux and xcopy in windows?

You can even try to run these commands from python

import os

os.system("cp file1 file2")

Hope this helps.

Upvotes: 0

Ofir
Ofir

Reputation: 8362

See the code in http://docs.python.org/library/shutil.html, then tweak it a little (e.g. try: around os.makedirs(dst)).

Upvotes: 1

Related Questions