如何在Python中查找递归空目录?
类似于GNU find
的find . -type d -empty -delete
我希望找到空目录,包括那些有空子目录的子目录(以及包含emtpy子目录等的子目录),但是没有删除它们。是否有任何现有的解决方案,或者我必须手动使用os.walk
(可能与topdown=False
并跟踪到目前为止找到的空子目录)?如何在Python中查找递归空目录?
好的,这是我的手动解决方案,使用os.walk
。功能is_empty
当然可以修改,例如,排除隐藏的文件,或者在我的例子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)
下面是使用一台发电机和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())
我不明白为什么topdown=False
是必要的,我不认为它改变了一切。
这确实认为只包含空目录的目录本身不是空的,但find . -type d -empty
也是如此。
虽然,有一些更多的测试,我看到find . -type d -empty -delete
不先删除空的子目录,再由上级目录,如果让他们空。但是使用os.walk并不适用,因为它在下降之前读取子目录列表,即使使用topdown=False
。
一个删除空的子目录树可能是一个递归解决方案:
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
好奇 - 啊,我在这个问题上看到我的错误,“找到。 -type d -empty'只能按照我使用'-delete'的方式递归地工作。恐怕我必须解决我的问题,虽然你的输入是赞赏,发电机确实听起来更好更好 – 2014-11-06 09:18:33
我修改[我自己的答案](http://stackoverflow.com/a/26775425/321973)包括一个生成器,但到目前为止,我必须存储迄今为止发现的所有空子分区,这就是为什么我需要'topdown = False'。但也许这是一种更简单的方法 – 2014-11-06 09:23:39
我会试图使用'os.walk',或'Popen' +'find'如果我是一定要在Unix上运行/ Linux – 2014-11-06 08:51:16
@SergeBallesta前者是我迄今为止最好的猜测。我想知道是否没有库函数,或者可能是一个'find'模块。这可能会简化很多事情。 – 2014-11-06 08:54:22
@SergeBallesta我[使用'os.walk']实现它(http://stackoverflow.com/a/26775425/321973),希望它足够Pythonic ... – 2014-11-06 09:06:07