Deleting folders in python recursively

145
November 23, 2019, at 02:20 AM

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?

Answer 1

Try shutil.rmtree:

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

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.

Answer 3

Try rmtree in shutil. in python std library

Answer 4

A bit late to the show but here is my pure Pathlib recursive directory unlinker

def rmdir(dir):
    dir = Path(dir)
    for item in dir.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    dir.rmdir()
rmdir(pathlib.Path("dir/"))
Answer 5

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')
Answer 6

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)
Answer 7

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)
Answer 8

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)
Answer 9

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()
Rent Charter Buses Company
READ ALSO
Get timestamp from pandas dataframe

Get timestamp from pandas dataframe

I can't figure out how to extract the timestamp from a pandas column

153
Solving sslv3 alert handshake failure when trying to use a client certificate

Solving sslv3 alert handshake failure when trying to use a client certificate

I'm trying to connect to a service that requires a certificate for authorizationThe process is that I send the service a CSR file

346
Matplotlib get subplot (axes) size?

Matplotlib get subplot (axes) size?

Just wandering - how can one obtain the size of a subplot (axes?) in Matplotlib?

213
Calculate 3D Plane that Rests on a 3D Surface

Calculate 3D Plane that Rests on a 3D Surface

I have about 300,000 points defining my 3D surfaceI would like to know if I dropped a infinitely stiff sheet onto my 3D surface, what the equation of that plane would be

125