Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 305
forvas Avatar asked May 06 '14 07:05

forvas


People also ask

How do you delete an empty directory in recursively?

Delete Empty Files in a Directory First, search all the empty files in the given directory and then, delete all those files. This particular part of the command, find . -type f -empty -print, will find all the empty files in the given directory recursively. Then, we add the -delete option to delete all those files.

How do I bulk delete empty folders?

Click to open My Computer. Choose the Search tab at the top line. In the opening Search Menu, set Size filter to Empty (0 KB) and check All subfolders option. From the list of the files and folders that don't take up any disk space, right-click the empty folder(s) and select Delete.

How do I delete multiple folders in Python?

rmtree('/path/to/dir') - and that this command will delete the directory even if the directory is not empty. On the other hand, os. rmdir() needs that the directory be empty.

How do I delete a recursive file in Python?

Path. rmdir() to delete an empty directory and shutil. rmtree() to recursively delete a directory and all of it's contents.


3 Answers

os.walk accepts optional topdown parameter (default: True).

By providing topdown=False, you can iterative from child directories first.

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)))
like image 187
falsetru Avatar answered Oct 16 '22 17:10

falsetru


Using the pathlib library in Python 3 this is a one-liner (other than includes). In the snippet below target_path is a string of the root of the tree you want to clean up:

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. os.removedirs() deletes all empty folders in above an empty leaf. If there are several empty leaves on a branch, deleting the last empty leaf will cause os.removedirs() to walk up the branch. So all empty dirs are gone in a single iteration of the loop with no recursion necessary!

like image 29
labroid Avatar answered Oct 16 '22 18:10

labroid


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()
like image 1
alper Avatar answered Oct 16 '22 16:10

alper