This is just for removing empty directories and also pulling out single files of directories. It seems to only answer one part of the question, sorry.
I added a loop at the end to keep trying till it can't find anymore. I made the function return a count of removed directories.
My access denied errors were fixed by: shutil.rmtree fails on Windows with 'Access is denied'
import os
import shutil
def onerror(func, path, exc_info):
"""
Error handler for ``shutil.rmtree``.
If the error is due to an access error (read only file)
it attempts to add write permission and then retries.
If the error is for another reason it re-raises the error.
Usage : ``shutil.rmtree(path, ignore_errors=False, onerror=onerror)``
"""
import stat
if not os.access(path, os.W_OK):
# Is the error an access error ?
os.chmod(path, stat.S_IWUSR)
func(path)
else:
raise
def get_empty_dirs(path):
# count of removed directories
count = 0
# traverse root directory, and list directories as dirs and files as files
for root, dirs, files in os.walk(path):
try:
# if a directory is empty there will be no sub-directories or files
if len(dirs) is 0 and len(files) is 0:
print u"deleting " + root
# os.rmdir(root)
shutil.rmtree(root, ignore_errors=False, onerror=onerror)
count += 1
# if a directory has one file lets pull it out.
elif len(dirs) is 0 and len(files) is 1:
print u"moving " + os.path.join(root, files[0]) + u" to " + os.path.dirname(root)
shutil.move(os.path.join(root, files[0]), os.path.dirname(root))
print u"deleting " + root
# os.rmdir(root)
shutil.rmtree(root, ignore_errors=False, onerror=onerror)
count += 1
except WindowsError, e:
# I'm getting access denied errors when removing directory.
print e
except shutil.Error, e:
# Path your moving to already exists
print e
return count
def get_all_empty_dirs(path):
# loop till break
total_count = 0
while True:
# count of removed directories
count = get_empty_dirs(path)
total_count += count
# if no removed directories you are done.
if count >= 1:
print u"retrying till count is 0, currently count is: %d" % count
else:
break
print u"Total directories removed: %d" % total_count
return total_count
count = get_all_empty_dirs(os.getcwdu()) # current directory
count += get_all_empty_dirs(u"o:\\downloads\\") # other directory
print u"Total of all directories removed: %d" % count
os.walk
to get at all the files, do anos.path.join
to get the full filepath for processing. ultimately delete the root (which will delete everything under it) – Mcfarlin