I want to copy all files from 2 directories to another, but when the files have the same name they get copied once(by one dir. not both) in the destination directory.
Here is the code:
def cp_files_tmp(src, dest):#copy dir's files into a dir
src_files = os.listdir(src)
for file_name in src_files:
full_file_name = os.path.join(src, file_name)
if (os.path.isfile(full_file_name)):
shutil.copy(full_file_name, dest)
dest = 'C:/temp/'
src_A= 'C:/sil/in/'
src_B= 'C:/olw/in/'
cp_files_tmp(src_A, dest) # cp files
cp_files_tmp(src_B, dest) # cp files
But what is an expected behaviour? If two files have the same name, then copying them simply overwrites the first one with the second, and there is no way it ends up differenly. You have to propose some kind of names unification, for example, if a file X exists, then copy the second X as X.tmp or something like this.
def cp_files_tmp(src, dest):
src_files = os.listdir(src)
for file_name in src_files:
full_file_name = os.path.join(src, file_name)
full_destination=os.path.join(dest,file_name)
if (os.path.isfile(full_file_name)):
while os.path.exists(full_destination):
full_destination += ".duplicate"
shutil.copy(full_file_name, full_destination)
dest = 'C:/temp/'
src_A= 'C:/sil/in/'
src_B= 'C:/olw/in/'
cp_files_tmp(src_A, dest) # cp files
cp_files_tmp(src_B, dest) # cp files
This should result in files being copied from C:/sil/in and C:/olw/in to C:/temp and in case of duplicates it simply changes the resulting name to FILE_NAME.duplicate
Related
I want to move all files containing a special string into another folder.
For example all files from testfolder/folder1and its subdirectories into testfolder/movedfiles.
I already wrote the code to extract all files from the folder and subfolder, but I am not quite sure how to move the files with the string (for example): abcd
import os
from fnmatch import fnmatch
root = "Directory"
string = "abcd"
def getListOfFiles(dirName):
# create a list of file and sub directories
# names in the given directory
listOfFile = os.listdir(dirName)
allFiles = list()
# Iterate over all the entries
for entry in listOfFile:
# Create full path
fullPath = os.path.join(dirName, entry)
# If entry is a directory then get the list of files in this directory
if os.path.isdir(fullPath):
allFiles = allFiles + getListOfFiles(fullPath)
else:
allFiles.append(fullPath)
return allFiles
# just to remove all the Directories before the current one
remove_foldername = "Directory Prefix"
allFiles = getListOfFiles(root)
filename = ""
filelist = []
for filename in allFiles:
if remove_foldername in filename:
filename = filename.replace(remove_foldername, "")
filelist.append(filename)
Now after all that, now the filelist would look like this:
['testfolder/folder/abcd.rtf', test/folder/folder1/abcd.rtf'] and so on.
Now I want to have all files moved to another directory (lets say to .../testfolder/movedfiles)
How would I do that?
I'm looking for a quick way to copy the entire directory structure (including sub folders and files), with the following conditions:
Copy file if it does not exist in the destination or source is newer
Allow excluding a list of sub folders i.e. ['temp', '.git']
Allow excluding files by type i.e. ['.txt', '.pyc', '*.zip']
I have seen some of the answers using shutil.copy and copytree but none is doing what I was looking for...
I am hoping this could by done by using one of the standard utilities by providing arguments etc. If not I will write a script to do it...
This is what I ended up writing... it does the job, I was hoping this basic functionality would be provided by one of the standard libraries...
import os, sys, pathlib, shutil
def copy_files_on_tree(srcdir, dstdir, sub_folder_to_include, extensions_to_include):
srcdir = str(pathlib.Path(srcdir)).replace('\\', '/')
dstdir = str(pathlib.Path(dstdir)).replace('\\', '/')
for dirpath, dirs, files in os.walk(pathlib.Path(srcdir)):
this_dir = dirpath.replace('\\', "/")
if os.path.basename(this_dir) in sub_folder_to_include:
dest_dir = this_dir.replace(srcdir, dstdir)
# create folder in the destinatin if it does not exist
pathlib.Path(dest_dir).mkdir(parents=True, exist_ok=True)
for filename in files:
dest_file = os.path.join(dest_dir, os.path.basename(filename))
source_file = os.path.join(this_dir, filename)
if os.path.isfile(source_file) and filename.endswith(extensions_to_include):
# copy file if destination is older by more than a second, or does not exist
if (not os.path.exists(dest_file)) or (os.stat(source_file).st_mtime - os.stat(dest_file).st_mtime > 1):
print (f'Copying {source_file} to {dest_dir}')
shutil.copy2(source_file, dest_dir)
else:
print (f'.....Skipping {source_file} to {dest_dir}')
srcdir = 'c:/temp/a'
dstdir = 'c:/temp/j'
sub_folder_to_include = ('a', 'aa','bb')
extensions_to_include = ('.py', '.png', '.gif', '.txt')
copy_files_on_tree(srcdir, dstdir, sub_folder_to_include, extensions_to_include)
This is the solution:
import os, sys, pathlib, shutil
def copy_files_on_tree(srcdir, dstdir, sub_folder_to_include, extensions_to_include):
srcdir = str(pathlib.Path(srcdir)).replace('\\', '/')
dstdir = str(pathlib.Path(dstdir)).replace('\\', '/')
for dirpath, dirs, files in os.walk(pathlib.Path(srcdir)):
this_dir = dirpath.replace('\\', "/")
if os.path.basename(this_dir) in sub_folder_to_include:
dest_dir = this_dir.replace(srcdir, dstdir)
# create folder in the destinatin if it does not exist
pathlib.Path(dest_dir).mkdir(parents=True, exist_ok=True)
for filename in files:
dest_file = os.path.join(dest_dir, os.path.basename(filename))
source_file = os.path.join(this_dir, filename)
if os.path.isfile(source_file) and filename.endswith(extensions_to_include):
# copy file if destination is older by more than a second, or does not exist
if (not os.path.exists(dest_file)) or (os.stat(source_file).st_mtime - os.stat(dest_file).st_mtime > 1):
print (f'Copying {source_file} to {dest_dir}')
shutil.copy2(source_file, dest_dir)
else:
print (f'.....Skipping {source_file} to {dest_dir}')
srcdir = 'c:/temp/a'
dstdir = 'c:/temp/j'
sub_folder_to_include = ('a', 'aa','bb')
extensions_to_include = ('.py', '.png', '.gif', '.txt')
copy_files_on_tree(srcdir, dstdir, sub_folder_to_include, extensions_to_include)
This is the error which I get:
The system cannot find the file specified: '1.jpg' -> '0.jpg'
even through i have a file named 1.jpg in the directory.
I'm making file renaming script that renames all files in the directory given with a number that increases +1 with every file.
import os
def moving_script():
directory = input("Give the directory")
xlist = os.listdir(directory)
counter = 0
for files in xlist:
os.rename(files, str(counter)+".jpg")
counter = counter + 1
moving_script()
It should be renaming all files, to "0.jpg", "1.jpg" etc
Code:
import os
def moving_script():
directory = input("Give the directory")
xlist = os.listdir(directory)
counter = 0
for files in xlist:
os.rename(os.path.join(directory, files),
os.path.join(directory, str(counter)+".jpg"))
counter = counter + 1
if __name__ == '__main__':
moving_script()
Results:
~/Documents$ touch file0 file1 file2 file3 file4
ls ~/Documents/
file0 file1 file2 file3 file4
$ python renamer.py
Give the directory'/home/suser/Documents'
$ ls ~/Documents/
0.jpg 1.jpg 2.jpg 3.jpg 4.jpg
os.listdir() will return filenames, but will not include path. Thus when you pass files to os.rename() it's looking for it in the current working directory, not the one where they are (i.e. supplied by the user).
import os
def moving_script():
directory = input("Give the directory")
counter = -1
for file_name in os.listdir(directory):
old_name = os.path.join(directory, file_name)
ext = os.path.splitext(file_name)[-1] # get the file extension
while True:
counter += 1
new_name = os.path.join(directory, '{}{}'.format(counter, ext))
if not os.path.exists(new_name):
os.rename(old_name, new_name)
break
moving_script()
note that this code detects what the file extension is. In your code you may rename a non-jpg file with .jpg extension. To avoid this you may change os.listdir(directory) to glob.glob(os.path.join(directory, *.jpg')) and it will iterate only over '*.jpg' files. Don't forget you need to import glob and also on Linux it's case-sensitive, so '*.jpg' will not return '*.JPG' files
EDIT: code updated to check if new file name already exists.
Basically I have 4 subfolders in my directory, and these are present in an array with the following structure:
path_list = [path1, path2, path3, path4]
When I run this code, I can scan all files in one of the folders.
for file_name in os.listdir(path_list[2]):
full_path = os.path.join(path_list[2], file_name)
...
new_sub = os.path.join(new_path, subdir_list[2])
final_path = os.path.join(new_sub, file_name)
imsave(final_path, img_norm)
I would like to find a way for the loop to scan the folder and once it has finished, an i++ occurred in path_list[i] and subdir_list[i] which it could change the value of the path. The loop should stop when it have scanned and modified all the files in the 4 folders.
You can wrap the entire thing in a for loop.
path_list = [path1, path2, path3]
subdir_list = [subdir1, subdir2, subdir3]
for i, _path in enumerate(path_list):
for file_name in os.listdir(_path):
full_path = os.path.join(_path, file_name)
...
new_sub = os.path.join(new_path, subdir_list[i])
final_path = os.path.join(new_sub, file_name)
imsave(final_path, img_norm)
I have a program that has a list of some files. I have to copy only the directories and the subdirectories from the list to a specified directories and don't need to copy the files. I tried this, but it doesn't work.
def copiarDirs():
items = list.curselection()
desti = tkFileDialog.askdirectory()
for dirs in os.walk(items, topdown=False):
for name in dirs:
#for i in items :
aux=root+"/"+list.get(i)
tryhard=("cp "+str(aux)+" "+str(desti))
os.system(tryhard)
Try this:
import os
def copyDirs(source, destination):
for subdir, dirs, files in os.walk(source):
for f in files:
dir = destination + os.path.join(subdir).split(':')[1]
if not os.path.exists(dir):
os.makedirs(dir)
sourceDir = 'D:\\Work\\'
destDir = 'D:\\Dest\\'
copyDirs(sourceDir, destDir) #calling function