Search code examples
pythonfile-copyingshutil

os.rename path error while moving file to subdirectory


I am new to python and coding in general. I have spent a lot of time trying to fix this error but I am not able to figure out how to do this. I have a main folder that contains a subfolder, I want to move files from the main folder to subfolder. This should be done easily by os.rename or shutil.move but I am not able to fix this error. Below is the code that I am using and the error that I am getting.

cdir=os.getcwd()
newdir=cdir+"\subfolder"
src=os.path.join(cdir, fname) 
dst=os.path.join(newdir, fname)
os.rename(src,dst)

The error shows a double backslash in the directories path i.e.

FileNotFoundError: [WinError 3] The system cannot find the path specified: 'E:\\ folder\\fname' -> 'E:\\folder\\subfolder\\fname'

the correct path would be with single back slashes. I am using windows 8.1 and python34. Can any one help me with this. I know this question must be a duplicate but I am unable to understand what I am doing wrong. Similar error is generated with shutil.move


Solution

  • The double backslashes are normal; they are not the cause of the error. Python always doubles up backslashes in string representations so that you can safely copy that value into a Python interpreter and reproduce the exact string:

    >>> print 'E:\\folder\\fname' 
    E:\folder\fname
    >>> 'E:\\folder\\fname' 
    'E:\\folder\\fname'
    >>> value = 'E:\\folder\\fname' 
    >>> value
    'E:\\folder\\fname'
    >>> print value
    E:\folder\fname
    

    Python does this because a single backslash is used in escape sequences; '\n' is a newline, but '\\n' is a backslash and the letter n.

    Your error lies elsewhere; most likely the subfolder has yet to be created; os.rename() or shutil.move() will not create parent folders for you.

    You can use the os.makedirs() function to ensure that all folders in a path are created:

    newdir = os.path.abspath('subfolder')  # will use the current working directory
    try:
        # ensure that it exists
        os.makedirs(newdir)
    except OSError:
        pass  # it is already there
    src = os.path.abspath(fname) 
    dst = os.path.join(newdir, fname)
    os.rename(src, dst)
    

    You also need to make sure you don't accidentally use single backslashes in your filename or subfolder definitions; \s is not a valid escape, but others are valid and can produce unexpected results. Double the backslash in strings defining paths, or use a raw string literal, or use forward slashes instead:

    >>> '\new'  # newline!
    '\new'
    >>> print '\new'  # produces a blank line in between
    
    ew
    >>> '\\new'
    '\\new'
    >>> print '\\new'
    \new
    >>> r'\new'
    '\\new'
    >>> '/new'
    '/new'
    

    Windows accepts forward slashes just fine; it doesn't care if the path separator is pointing forward or backward.