views:

3039

answers:

6

I'm confused with file moving under python. Under windows commandline, if i have directory c:\a and a directory c:\b, i can do

move c:\a c:\b

which moves a to b result is directory structure c:\b\a

If I try this with os.rename or shutil.move:

os.rename("c:/a", "c:/b")

I get

WindowsError: [Error 17] Cannot create a file when that file already exists

If I move a single file under c:\a, it works.

In python how do i move a directory to another existing directory?

A: 

You will need to state the full path it's being moved to:

src = 'C:\a'
dst_dir = 'C:\b'
last_part = os.path.split(src)[1]
os.rename(src, os.path.join(dst_dir, last_part))

Actually, it looks like shutil.move will do what you want by looking at its documentation:

If the destination is a directory or a symlink to a directory, the source is moved inside the directory.

(And its source.)

cdleary
Unfortuneatly this will fail if the files are located on different volumes.
wuub
@wuub: What makes you say that? The docs say there's quirky behavior in some UNIX filesystems, but the OP is talking about Windows.
cdleary
Hmm, this is straightforward for a single directory, but moving a big directory structure to another folder is really inconvenient this way. Quite strange that python doesn't support this.
Ash
It does -- shutil.move you can use via: import shutil; shutil.move(src, dst)
cdleary
@cdleary: You're right, I advice against os.rename because of past problems I had with it while coding a toy FUSE filesystem, shutil on the other hand works great no matter what the OS is.
wuub
+2  A: 

You can try using the Shutil module.

Key
Specifically shutil.move(srcFile, destFile)
PTBNL
+3  A: 

os.rename("c:/a", "c:/b/a") is equivalent to "move c:\a c:\b" under windows commandline

sunqiang
+1  A: 

When i need many file system operations I prefer using 'path' module:
http://pypi.python.org/pypi/path.py/2.2

It's quite a good and lightweight wrapper around built-in 'os.path' module.

Also code:

last_part = os.path.split(src)[1]

is a bit strange, cause there is special function for this:

last_part = os.path.basename(src)
Mihail
Excellent point -- forgot about basename. I don't like how there's more than one way to do that. ;-)
cdleary
+1  A: 

os.rename("c:/a/", "c:/b"/) --> Changes the name of folder a in folder b

os.rename("c:/a/", "c:/b/a") --> Put folder b into folder a

luc
A: 

Using Twisted's FilePath:

from twisted.python.filepath import FilePath
FilePath("c:/a").moveTo(FilePath("c:/b/a"))

or, more generally:

from twisted.python.filepath import FilePath
def moveToExistingDir(fileOrDir, existingDir):
    fileOrDir.moveTo(existingDir.child(fileOrDir.basename()))
moveToExistingDir(FilePath("c:/a"), FilePath("c:/b"))
Glyph