78

Here is below code which will move and replace individual file:

import shutil
import os
src = 'scrFolder'
dst = './dstFolder/'
filelist = []

files = os.listdir( src )
for filename in files:
    filelist.append(filename)
    fullpath = src + '/' + filename
    shutil.move(fullpath, dst)

If I execute same command and moving file which already existed in dst folder, I am getting shutil.Error: Destination path './dstFolder/file.txt' already exists. How to do move and replace if same file name already exists?

martineau
  • 119,623
  • 25
  • 170
  • 301
user1891916
  • 951
  • 1
  • 8
  • 9
  • Special case of [Python - Move and overwrite files and folders - Stack Overflow](https://stackoverflow.com/questions/7419665/python-move-and-overwrite-files-and-folders) in which this only cover files. – user202729 Mar 30 '23 at 00:38

2 Answers2

155

If you specify the full path to the destination (not just the directory) then shutil.move will overwrite any existing file:

shutil.move(os.path.join(src, filename), os.path.join(dst, filename))
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • 6
    does this work as well on a network drive, i have a full path to the file but it's not overriting, exiting with "File Exists" – user1767754 Jun 07 '16 at 18:07
  • @user1767754 I'd only expect that to happen if the source is a symbolic link. Perhaps you could ask a follow-up question? – ecatmur Jun 07 '16 at 18:28
  • 23
    @ecatmur I independently tested the same thing. 1. if the destination directory has the source filename already and you do `shutil.move(src_filename, dst_dirname)` an error is raised `Error: Destination path 'dst_dirname/src_filename' already exists`. 2. HOWEVER if you do `dst_filename = os.path.join(dst_dirname, os.path.basename(src_filename)); shutil.move(src_filename, dst_filename)` --> then you don't get an exception raised. – Trevor Boyd Smith Aug 11 '17 at 11:31
  • how can I modify this when I want to delete the old files and save the new one @ecatmur – ak3191 Nov 13 '18 at 14:23
  • @ak3191 overwrite means deleting the old file and having new one. – Timo May 07 '21 at 19:16
  • 1
    You don't need to specify the full path. If the filename is included in the destination path (relative or absolute) shutil will overwrite. – B. Bogart Jun 17 '21 at 20:46
  • 8
    this looks a bit voodoo to me — why should there be different semantics for absolute and relative paths? this breaks the [least surprise principle](https://en.wikipedia.org/wiki/Principle_of_least_astonishment) that python is so proudly following. I was expecting something like `exist_ok=True`, similar to what `mkdir()` does. – ccpizza Sep 28 '21 at 15:35
  • 4
    @TrevorBoydSmith, python3.6 reports the destination existing error, but it works fine wih Python 3.9.7. – Fisher Dec 08 '21 at 09:34
  • 1
    Not happy with this solution. If you have a different python version or other circumstances this will fail. - Not downvoting this as it could still be helpful for some prototype script – Matthias Herrmann Mar 22 '22 at 08:24
  • @B.Bogart is right- you just need to include the filename in the dest path – grantr Mar 27 '22 at 06:00
  • I suspect this is inefficient because according to the function documentation it will * first attempt to use `move`, then if it fails (it does) then * it will use `copy` then delete the source. And copying is definitely slower than moving. – user202729 Mar 30 '23 at 00:28
8

I got it to overwrite by providing a full path for both source and target in the move command... remember to add double slash for Windows paths.

# this is to change directories (type your own)
os.chdir("C:\REPORTS\DAILY_REPORTS")

# current dir  (to verify)
cwd = os.getcwd() 
src = cwd
dst = cwd + '\\XLS_BACKUP\\'

shutil.move(os.path.join(src, file), os.path.join(dst, file))

# nice and short.
Andres Martinez
  • 214
  • 2
  • 5