简体   繁体   English

如何在Python3中递归删除空文件夹?

[英]How to delete recursively empty folders in Python3?

I am trying to remove the empty folders of a directory.我正在尝试删除目录的空文件夹。

def remove_empty_dir(path):
    try:
        os.rmdir(path)
    except OSError:
        pass

def remove_empty_dirs(path):
    for root, dirnames, filenames in os.walk(path):
        for dirname in dirnames:
            remove_empty_dir(os.path.realpath(os.path.join(root, dirname)))

remove_empty_dirs(path)

I have also tried with:我也试过:

import shutil
shutil.rmtree(path)

But that removes everything, even those folders with contents.但这会删除所有内容,甚至是那些包含内容的文件夹。 The problem is that I need to do it from inside to outside , this way if I have:问题是我需要从内到外这样做,如果我有:

root_folder
  child_folder1
    grandchild_folder1.1 (empty)
  child_folder2
    granchild_folder2.1
    granchild_folder2.2 (empty)

The program should delete grandchild_folder1.1, child_folder1 and child_folder2.2, but not the rest.程序应该删除grandchild_folder1.1、child_folder1 和child_folder2.2,但不删除其余部分。

os.walk accepts optional topdown parameter (default: True). os.walk接受可选的topdown参数(默认值:True)。

By providing topdown=False , you can iterative from child directories first.通过提供topdown=False ,您可以首先从子目录进行迭代。

def remove_empty_dirs(path):
    for root, dirnames, filenames in os.walk(path, topdown=False):
        for dirname in dirnames:
            remove_empty_dir(os.path.realpath(os.path.join(root, dirname)))

Using the pathlib library in Python 3 this is a one-liner (other than includes).使用 Python 3 中的 pathlib 库,这是一个单行(包含除外)。 In the snippet below target_path is a string of the root of the tree you want to clean up:在 target_path 下面的代码段中,是您要清理的树根的字符串:

from pathlib import Path
import os

[os.removedirs(p) for p in Path(target_path).glob('**/*') if p.is_dir() and len(list(p.iterdir())) == 0]

To make it a little less dense and easier to follow, this is the same thing written without the list comprehension为了让它不那么密集并且更容易理解,这是在没有列表理解的情况下编写的相同内容

for p in Path(target_path).glob('**/*'):
    if p.is_dir() and len(list(p.iterdir())) == 0:
        os.removedirs(p)

The interesting feature here is the if statement filters for empty directories that are leaves on the filesystem tree.这里有趣的功能是 if 语句过滤文件系统树上的叶子的空目录。 os.removedirs() deletes all empty folders in above an empty leaf. os.removedirs() 删除空叶子上方的所有空文件夹。 If there are several empty leaves on a branch, deleting the last empty leaf will cause os.removedirs() to walk up the branch.如果一个分支上有几个空叶子,删除最后一个空叶子会导致 os.removedirs() 向上走分支。 So all empty dirs are gone in a single iteration of the loop with no recursion necessary!所以所有空目录都在循环的一次迭代中消失了,不需要递归!

def remove_empty_dirs(dir_path):
    p1 = subprocess.Popen(["find", dir_path, "-type", "d", "-empty", "-print0"], stdout=subprocess.PIPE,)
    p2 = subprocess.Popen(["xargs", "-0", "-r", "rmdir"], stdin=p1.stdout, stdout=subprocess.PIPE)
    p1.stdout.close()
    p2.communicate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM