Deleting folders in python recursively

PythonDirectory

Python Problem Overview


I'm having a problem with deleting empty directories. Here is my code:

for dirpath, dirnames, filenames in os.walk(dir_to_search):
    //other codes

    try:
        os.rmdir(dirpath)
    except OSError as ex:
        print(ex)

The argument dir_to_search is where I'm passing the directory where the work needs to be done. That directory looks like this:

test/20/...
test/22/...
test/25/...
test/26/...

Note that all the above folders are empty. When I run this script the folders 20,25 alone gets deleted! But the folders 25 and 26 aren't deleted, even though they are empty folders.

Edit:

The exception that I'm getting are:

[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/26'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/25'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27/tmp'

Where am I making a mistake?

Python Solutions


Solution 1 - Python

Try shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')

Solution 2 - Python

Here's my pure pathlib recursive directory unlinker:

from pathlib import Path

def rmdir(directory):
    directory = Path(directory)
    for item in directory.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    directory.rmdir()

rmdir(Path("dir/"))

Solution 3 - Python

The default behavior of os.walk() is to walk from root to leaf. Set topdown=False in os.walk() to walk from leaf to root.

Solution 4 - Python

Try rmtree() in shutil from the Python standard library

Solution 5 - Python

better to use absolute path and import only the rmtree function from shutil import rmtree as this is a large package the above line will only import the required function.

from shutil import rmtree
rmtree('directory-absolute-path')

Solution 6 - Python

Just for the next guy searching for a micropython solution, this works purely based on os (listdir, remove, rmdir). It is neither complete (especially in errorhandling) nor fancy, it will however work in most circumstances.

def deltree(target):
    print("deltree", target)
    for d in os.listdir(target):
        try:
            deltree(target + '/' + d)
        except OSError:
            os.remove(target + '/' + d)

    os.rmdir(target)

Solution 7 - Python

The command (given by Tomek) can't delete a file, if it is read only. therefore, one can use -

import os, sys
import stat

def del_evenReadonly(action, name, exc):
    os.chmod(name, stat.S_IWRITE)
    os.remove(name)
	
if  os.path.exists("test/qt_env"):
	shutil.rmtree('test/qt_env',onerror=del_evenReadonly)

Solution 8 - Python

Here is a recursive solution:

def clear_folder(dir):
    if os.path.exists(dir):
        for the_file in os.listdir(dir):
            file_path = os.path.join(dir, the_file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                else:
                    clear_folder(file_path)
                    os.rmdir(file_path)
            except Exception as e:
                print(e)

Solution 9 - Python

The command os.removedirs is the tool for the job, if you are only looking for a single path to delete, e.g.:

os.removedirs("a/b/c/empty1/empty2/empty3")

will remove empty1/empty2/empty3, but leave a/b/c (presuming that c has some other contents).

    removedirs(name)
        removedirs(name)
        
        Super-rmdir; remove a leaf directory and all empty intermediate
        ones.  Works like rmdir except that, if the leaf directory is
        successfully removed, directories corresponding to rightmost path
        segments will be pruned away until either the whole path is
        consumed or an error occurs.  Errors during this latter phase are
        ignored -- they generally mean that a directory was not empty.

Solution 10 - Python

Here's another pure-pathlib solution, but without recursion:

from pathlib import Path
from typing import Union

def del_empty_dirs(base: Union[Path, str]):
    base = Path(base)
    for p in sorted(base.glob('**/*'), reverse=True):
        if p.is_dir():
            p.chmod(0o666)
            p.rmdir()
        else:
            raise RuntimeError(f'{p.parent} is not empty!')
    base.rmdir()

Solution 11 - Python

For Linux users, you can simply run the shell command in a pythonic way

import os
os.system("rm -r /home/user/folder1  /home/user/folder2  ...")

If facing any issue then instead of rm -r use rm -rf but remember f will delete the directory forcefully.

Where rm stands for remove, -r for recursively and -rf for recursively + forcefully.

Note: It doesn't matter either the directories are empty or not, they'll get deleted.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsriramView Question on Stackoverflow
Solution 1 - PythonTomekView Answer on Stackoverflow
Solution 2 - PythonmitchView Answer on Stackoverflow
Solution 3 - PythonlqsView Answer on Stackoverflow
Solution 4 - Pythonmicroo8View Answer on Stackoverflow
Solution 5 - PythonGajenderView Answer on Stackoverflow
Solution 6 - PythonJustus WingertView Answer on Stackoverflow
Solution 7 - PythonMonirView Answer on Stackoverflow
Solution 8 - PythonTobias ErnstView Answer on Stackoverflow
Solution 9 - PythonCireoView Answer on Stackoverflow
Solution 10 - PythonpepoluanView Answer on Stackoverflow
Solution 11 - PythonGarvitView Answer on Stackoverflow