Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy file if it doesn't already exist [duplicate]

I'm fairly new to python, and I'm wondering how I can copy and paste a file from one location to another with first checking to see if the copied file exists in the destination folder?

The reason I want to check if the file exists is this script will be put on a task scheduler and run on a set schedule, so I don't want to be copying everything every single time, just those files that don't exist in the destination folder?

Thanks in advance!

like image 451
mpboyle Avatar asked Dec 16 '13 16:12

mpboyle


People also ask

What does cp do if file exists?

If the Destination does NOT exist, cp will assume the Destination is to be a file and will create a copy of the Source file. If the Destination file exists cp will overwrite the destination file unless the -i option (see below) is specified.

How do you copy only those files that are not in the destination?

If you are copying files using drag-drop or copy/paste, you may simply choose “Skip this file” or “Skip these files” option to not overwrite the files that are already existed at the destination folder. Or, if you are using command line copy, you can answer N to bypass these files that are already existed.

How do you force copy a file in Python?

For each file, simply shutil. copy() and the file will be created or overwritten, whichever is appropriate.

How do I copy unique files in Linux?

To copy files and directories use the cp command under a Linux, UNIX-like, and BSD like operating systems. cp is the command entered in a Unix and Linux shell to copy a file from one place to another, possibly on a different filesystem.


1 Answers

import glob
import os.path
import shutil

SRC_DIR = #your source directory
TARG_DIR = #your target directory

GLOB_PARMS = "*" #maybe "*.pdf" ?

for file in glob.glob(os.path.join(SRC_DIR, GLOB_PARMS)):
    if file not in glob.glob(os.path.join(TARG_DIR, GLOB_PARMS)):
        shutil.copy(file,TARG_DIR)
    else:
        print("{} exists in {}".format(
            file,os.path.join(os.path.split(TARG_DIR)[-2:])))
        # This is just a print command that outputs to console that the
        # file was already in directory

I'm assuming you're trying to send a whole folder over with this command, otherwise glob uses pretty easy to understand interface. glob.glob("*.txt") will grab all the files with a .txt extension, etc. Shouldn't be too hard to tweak this to exactly what you want.

It's important to note that file copy usually involves a race condition. Basically, time passes between checking to see if the file isn't in TARG_DIR (if file not in glob.glob(TARG_DIR)) and actually copying it there (shutil.copy(file,TARG_DIR)). In that amount of time, the file could end up there, which will cause shutil.copy to overwrite the file. This may not be your intended functionality, in which case you should look into a different method. I don't know of a good one without some research that will try to copy a file but return an exception if that file already exists.

Try/Except blocks, as another answer mentioned, may be useful here as well if it's possible you won't have write access to the directory when your script runs. shutil.copy will return an IOError exception if that is the case. I believe glob will just return an empty list if you don't have read access to your source directory (which in turn will feed nothing through the "For" loop, so you won't have any errors there).

EDIT: Apparently glob doesn't work the way I remembered it did, sorry about that.

like image 174
Adam Smith Avatar answered Oct 13 '22 08:10

Adam Smith