I have a large directory with many subdirectories that I am trying to sort, I am trying to copy specific file types to a new folder, but I want to maintain the original subdirectories.
def copyFile(src, dest):
try:
shutil.copy(src,dest)
except shutil.Error as e:
print('Error: %s' % e)
except IOError as e:
print('Error: %s' % s.strerror)
for root, directories, files in os.walk(directory):
for directoryname in directories:
dirpath = os.path.join(root,directoryname)
dir_paths.append(dirpath)
dir_names.append(directoryname)
if not os.listdir(dirpath): #Cheching if directory is empty
print("Empty")
EmptyDirs.append(directoryname) #Add directory name to empty directory list
EmptyDirPath.append(dirpath)
else:
pass
for filename in files:
filepath = os.path.join(root,filename)
file_paths.append(filepath)
file_names.append(filename)
if filename.lower().endswith(".sldasm"):
print(filename.encode('utf8'))
SolidModels.append(filename)
copyFile(filepath,dest)
elif filename.lower().endswith(".sldprt"):
print(filename.encode('utf8'))
SolidModels.append(filename)
copyFile(filepath,dest)
else:
pass
This is the code I am using now, but it just copies the files without copying the subdirectories they were originally in, so they are completely unorganized in the new folder.
This is the new code using copytree, however now the specific files will not copy, only the subdirectories do.
def copytree(src, dst, symlinks=False, ignore=None):
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else:
if src is "*.sldasm":
copy2(srcname, dstname)
elif src is "*.sldprt":
copy2(srcname, dstname)
except (IOError, os.error) as why:
errors.append((srcname, dstname, str(why)))
You can do what you want with the
shutil.copytree()
function by using its optionalignore
keyword argument. The tricky part is that, if given, it must be a callable that returns what, in each directory, should not be copied, rather than what should be.However it possible to write a factory function similar to
shutil.ignore_patterns()
that creates a function that does what's needed, and use that as theignore
keyword argument's value.The function returned first determines what files to keep via the
fnmatch.filter()
function, then removes them from the list of everything which is in the given directory, unless they're a sub-directory name, in which case they're left in for later [recursive] processing. (This is what makes it copy the whole tree and what was probably wrong with your attempt to write your owncopytree()
function).