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

Tob*_*ler 4 python directory-structure subdirectory

同样以GNU findfind . -type d -empty -delete我想找到空目录,包括那些(含emtpy子目录等和子目录)中的子目录,但不删除它们.是否有任何现有的解决方案或我必须手动使用os.walk(可能与topdown=False目前为止发现的空子目录有关并跟踪)?

Rem*_*ich 7

这是一个使用生成器的简单解决方案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())
Run Code Online (Sandbox Code Playgroud)

我不明白为什么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
Run Code Online (Sandbox Code Playgroud)


Tob*_*ler 2

好的,这是我使用的手动解决方案os.walkis_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)
Run Code Online (Sandbox Code Playgroud)