如何在Python中查找递归空目录?

问题描述:

类似于GNU findfind . -type d -empty -delete我希望找到空目录,包括那些有空子目录的子目录(以及包含emtpy子目录等的子目录),但是没有删除它们。是否有任何现有的解决方案,或者我必须手动使用os.walk(可能与topdown=False并跟踪到目前为止找到的空子目录)?如何在Python中查找递归空目录?

+0

我会试图使用'os.walk',或'Popen' +'find'如果我是一定要在Unix上运行/ Linux – 2014-11-06 08:51:16

+0

@SergeBallesta前者是我迄今为止最好的猜测。我想知道是否没有库函数,或者可能是一个'find'模块。这可能会简化很多事情。 – 2014-11-06 08:54:22

+0

@SergeBallesta我[使用'os.walk']实现它(http://*.com/a/26775425/321973),希望它足够Pythonic ... – 2014-11-06 09:06:07

好的,这是我的手动解决方案,使用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 
+0

好奇 - 啊,我在这个问题上看到我的错误,“找到。 -type d -empty'只能按照我使用'-delete'的方式递归地工作。恐怕我必须解决我的问题,虽然你的输入是赞赏,发电机确实听起来更好更好 – 2014-11-06 09:18:33

+0

我修改[我自己的答案](http://*.com/a/26775425/321973)包括一个生成器,但到目前为止,我必须存储迄今为止发现的所有空子分区,这就是为什么我需要'topdown = False'。但也许这是一种更简单的方法 – 2014-11-06 09:23:39