Similarly to GNU find
's find . -type d -empty -delete
find . -type d -empty -delete
I'd like to find empty directories including those with empty subdirectories (and subdirectories containing emtpy subdirs etc.), but without deleting them . Is there any existing solution or do I have to manually use os.walk
(probably with topdown=False
and keeping track of the empty subdirectories found so far)?
Here is a simple solution using a generator and os.walk
:
import os
def find_empty_dirs(root_dir='.'):
for dirpath, dirs, files in os.walk(root_dir):
if not dirs and not files:
yield dirpath
print list(find_empty_dirs())
I don't see why topdown=False
is necessary, I don't think it changes anything.
This does consider directories that only contain empty directories to be non-empty themselves, but then so does find . -type d -empty
find . -type d -empty
.
Although, with some more testing, I see find . -type d -empty -delete
find . -type d -empty -delete
does delete the empty subdirectories first, and then the higher directories if that made them empty. But using os.walk for that won't work, as it reads the list of subdirectories before descending, even with topdown=False
.
A recursive solution that deletes empty subdirectory trees could be:
import os
def recursive_delete_if_empty(path):
"""Recursively delete empty directories; return True
if everything was deleted."""
if not os.path.isdir(path):
# If you also want to delete some files like desktop.ini, check
# for that here, and return True if you delete them.
return False
# Note that the list comprehension here is necessary, a
# generator expression would shortcut and we don't want that!
if all([recursive_delete_if_empty(os.path.join(path, filename))
for filename in os.listdir(path)]):
# Either there was nothing here or it was all deleted
os.rmdir(path)
return True
else:
return False
Ok, here's my manual solution using os.walk
. The function is_empty
can of course be modified, eg to exclude hidden files, or in my example desktop.ini
:
import os
def empty_dirs(root_dir='.', recursive=True):
empty_dirs = []
for root, dirs, files in os.walk(root_dir, topdown=False):
#print root, dirs, files
if recursive:
all_subs_empty = True # until proven otherwise
for sub in dirs:
full_sub = os.path.join(root, sub)
if full_sub not in empty_dirs:
#print full_sub, "not empty"
all_subs_empty = False
break
else:
all_subs_empty = (len(dirs) == 0)
if all_subs_empty and is_empty(files):
empty_dirs.append(root)
yield root
def is_empty(files):
return (len(files) == 0 or files == ['desktop.ini'])
def find_empty_dirs(root_dir='.', recursive=True):
return list(empty_dirs(root_dir, recursive))
print find_empty_dirs(recursive=False)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.