How can I delete the contents of a local folder in Python?
The current project is for Windows, but I would like to see *nix also.
How can I delete the contents of a local folder in Python?
The current project is for Windows, but I would like to see *nix also.
import os, shutil
folder = '/path/to/folder'
for filename in os.listdir(folder):
file_path = os.path.join(folder, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (file_path, e))
except Exception as e:
that reads W0703: Catching too general exception Exception
. Is there a more specific Exception to catch or should I ignore it? –
Tipper You can simply do this:
import os
import glob
files = glob.glob('/YOUR/PATH/*')
for f in files:
os.remove(f)
You can of course use an other filter in you path, for example : /YOU/PATH/*.txt for removing all text files in a directory.
*
won't list hidden files, we should also add glob.glob('path/.*)
–
Eclosion import sh; sh.rm(files)
–
Ginnygino import sh; sh.rm(files)
does look prettier, you run into trouble if there are more than 1024 files in the directory. –
Valorize You can delete the folder itself, as well as all its contents, using shutil.rmtree
:
import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)
Delete an entire directory tree; path must point to a directory (but not a symbolic link to a directory). If ignore_errors is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are handled by calling a handler specified by onerror or, if that is omitted, they raise an exception.
rmtree
. Like os.makedirs(dir)
–
Stevens OSError: [Errno 16] Device or resource busy
–
Seedcase os.remove()
does not work, running Mac on Big Sur –
Rustie Expanding on mhawke's answer this is what I've implemented. It removes all the content of a folder but not the folder itself. Tested on Linux with files, folders and symbolic links, should work on Windows as well.
import os
import shutil
for root, dirs, files in os.walk('/path/to/folder'):
for f in files:
os.unlink(os.path.join(root, f))
for d in dirs:
shutil.rmtree(os.path.join(root, d))
walk
is used to split dirs vs. files, which must be handled differently. You could also use os.listdir
, but you'd have to check if each entry is a dir or file manually. –
Roundtheclock os.walk
won't recurse here, because it returns a generator the only recursively looks into subdirectories when you try to advance it, and by the time you've done your first iteration of this loop, there are no subdirectories left to look at. In essence, os.walk
is just being used here as an alternative way of distinguishing top-level folders from top-level files; the recursion isn't being used and we pay no performance cost for it. It's eccentric, though, and I agree that the approach you suggest is better simply because it's more explicit and readable. –
Olethea I'm surprised nobody has mentioned the awesome pathlib
to do this job.
If you only want to remove files in a directory it can be a oneliner
from pathlib import Path
[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()]
To also recursively remove directories you can write something like this:
from pathlib import Path
from shutil import rmtree
for path in Path("/path/to/folder").glob("**/*"):
if path.is_file():
path.unlink()
elif path.is_dir():
rmtree(path)
.iterdir()
instead of .glob(...)
should also work. –
Maldon Using rmtree
and recreating the folder could work, but I have run into errors when deleting and immediately recreating folders on network drives.
The proposed solution using walk does not work as it uses rmtree
to remove folders and then may attempt to use os.unlink
on the files that were previously in those folders. This causes an error.
The posted glob
solution will also attempt to delete non-empty folders, causing errors.
I suggest you use:
folder_path = '/path/to/folder'
for file_object in os.listdir(folder_path):
file_object_path = os.path.join(folder_path, file_object)
if os.path.isfile(file_object_path) or os.path.islink(file_object_path):
os.unlink(file_object_path)
else:
shutil.rmtree(file_object_path)
rmtree
to remove folders and then may attempt to use os.unlink
on the files that were previously in those folders" - this isn't what I witness using a local drive on my Mac. The generator returned from os.walk
simply doesn't yield a second element if you've deleted all the folders on the first iteration. I can believe that there's some file system or environment for which this is true (e.g. a network drive), but it's definitely not a universal truth. –
Olethea islink
check here to handle symlinks to directories correctly. I've added such a check to the accepted answer. –
Olethea Using os.scandir and context manager protocol in Python 3.6+:
import os
import shutil
with os.scandir(target_dir) as entries:
for entry in entries:
if entry.is_dir() and not entry.is_symlink():
shutil.rmtree(entry.path)
else:
os.remove(entry.path)
Earlier versions of Python:
import os
import shutil
# Gather directory contents
contents = [os.path.join(target_dir, i) for i in os.listdir(target_dir)]
# Iterate and remove each item in the appropriate manner
[shutil.rmtree(i) if os.path.isdir(i) and not os.path.islink(i) else os.remove(i) for i in contents]
os.scandir
has any advantages/disadvantages over other approaches in other answers? –
Pines This:
Code:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
try:
shutil.rmtree(filepath)
except OSError:
os.remove(filepath)
As many other answers, this does not try to adjust permissions to enable removal of files/directories.
Notes: in case someone down voted my answer, I have something to explain here.
shutil.rmtree()
could be used to delete a directory tree. I've used it many times in my own projects. But you must realize that the directory itself will also be deleted by shutil.rmtree()
. While this might be acceptable for some, it's not a valid answer for deleting the contents of a folder (without side effects).shutil.rmtree()
and rebuild it with os.mkdir()
. And you'll get an empty directory with default (inherited) owner and mode bits instead. While you might have the privilege to delete the contents and even the directory, you might not be able to set back the original owner and mode bits on the directory (e.g. you're not a superuser).Here's a long and ugly, but reliable and efficient solution.
It resolves a few problems which are not addressed by the other answerers:
shutil.rmtree()
on a symbolic link (which will pass the os.path.isdir()
test if it links to a directory; even the result of os.walk()
contains symbolic linked directories as well).Here's the code (the only useful function is clear_dir()
):
import os
import stat
import shutil
# https://mcmap.net/q/55079/-deleting-read-only-directory-in-python
def _remove_readonly(fn, path_, excinfo):
# Handle read-only files and directories
if fn is os.rmdir:
os.chmod(path_, stat.S_IWRITE)
os.rmdir(path_)
elif fn is os.remove:
os.lchmod(path_, stat.S_IWRITE)
os.remove(path_)
def force_remove_file_or_symlink(path_):
try:
os.remove(path_)
except OSError:
os.lchmod(path_, stat.S_IWRITE)
os.remove(path_)
# Code from shutil.rmtree()
def is_regular_dir(path_):
try:
mode = os.lstat(path_).st_mode
except os.error:
mode = 0
return stat.S_ISDIR(mode)
def clear_dir(path_):
if is_regular_dir(path_):
# Given path is a directory, clear its content
for name in os.listdir(path_):
fullpath = os.path.join(path_, name)
if is_regular_dir(fullpath):
shutil.rmtree(fullpath, onerror=_remove_readonly)
else:
force_remove_file_or_symlink(fullpath)
else:
# Given path is a file or a symlink.
# Raise an exception here to avoid accidentally clearing the content
# of a symbolic linked directory.
raise OSError("Cannot call clear_dir() on a symbolic link")
os.remove
, unlike the rm
utility, is happy to delete read-only files as long as you own them. Meanwhile, if it's a file you don't own that you only have readonly access to, then you can't delete it or change its permissions. I don't know any situation on any system where you'd be unable to delete a readonly file with os.remove
yet be able to change its permissions. Furthermore, you use lchmod
, which doesn't exist on my Mac, nor on Windows according to its docs. What platform is this code meant for?! –
Olethea As a oneliner:
import os
# Python 2.7
map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
# Python 3+
list( map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) ) )
A more robust solution accounting for files and directories as well would be (2.7):
def rm(f):
if os.path.isdir(f): return os.rmdir(f)
if os.path.isfile(f): return os.unlink(f)
raise TypeError, 'must be either file or directory'
map( rm, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
–
Sanjuana list(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
–
Sanjuana map
in list
to actually iterate. See https://mcmap.net/q/55080/-getting-a-map-to-return-a-list-in-python-3-x-duplicate –
Duggins I used to solve the problem this way:
import shutil
import os
shutil.rmtree(dirpath)
os.mkdir(dirpath)
(that's on me)
but it does not.. so this answer is still Okay! Depends who reads it on the internet and how they would think this answer would affect their program. –
Maillot To delete all files inside a folder a I use:
import os
for i in os.listdir():
os.remove(i)
IsADirectoryError
exception will be raised. –
Booby To delete all the files inside the directory as well as its sub-directories, without removing the folders themselves, simply do this:
import os
mypath = "my_folder" #Enter your path here
for root, dirs, files in os.walk(mypath, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
# Add this block to remove folders
for dir in dirs:
os.rmdir(os.path.join(root, dir))
# Add this line to remove the root folder at the end
os.rmdir(mypath)
If you are using a *nix system, why not leverage the system command?
import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)
os.system
+ string processing + improper quoting = shell injection –
Vacillate rm -r %s/*
instead –
Oblique You might be better off using os.walk()
for this.
os.listdir()
doesn't distinguish files from directories and you will quickly get into trouble trying to unlink these. There is a good example of using os.walk()
to recursively remove a directory here, and hints on how to adapt it to your circumstances.
I konw it's an old thread but I have found something interesting from the official site of python. Just for sharing another idea for removing of all contents in a directory. Because I have some problems of authorization when using shutil.rmtree() and I don't want to remove the directory and recreate it. The address original is http://docs.python.org/2/library/os.html#os.walk. Hope that could help someone.
def emptydir(top):
if(top == '/' or top == "\\"): return
else:
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
I had to remove files from 3 separate folders inside a single parent directory:
directory
folderA
file1
folderB
file2
folderC
file3
This simple code did the trick for me: (I'm on Unix)
import os
import glob
folders = glob.glob('./path/to/parentdir/*')
for fo in folders:
file = glob.glob(f'{fo}/*')
for f in file:
os.remove(f)
Hope this helps.
Yet Another Solution:
import sh
sh.rm(sh.glob('/path/to/folder/*'))
sh
isn't part of the standard library and needs installing from PyPI before you can use it. Also, since this actually invokes rm
in a subprocess, it won't work on Windows where rm
doesn't exist. It will also raise an exception if the folder contains any subdirectories. –
Olethea Well, I think this code is working. It will not delete the folder and you can use this code to delete files having the particular extension.
import os
import glob
files = glob.glob(r'path/*')
for items in files:
os.remove(items)
use this function
import os
import glob
def truncate(path):
files = glob.glob(path+'/*.*')
for f in files:
os.remove(f)
truncate('/my/path')
Answer for a limited, specific situation: assuming you want to delete the files while maintainig the subfolders tree, you could use a recursive algorithm:
import os
def recursively_remove_files(f):
if os.path.isfile(f):
os.unlink(f)
elif os.path.isdir(f):
for fi in os.listdir(f):
recursively_remove_files(os.path.join(f, fi))
recursively_remove_files(my_directory)
Maybe slightly off-topic, but I think many would find it useful
os.walk
in the way shown at https://mcmap.net/q/53724/-how-to-delete-the-contents-of-a-folder is perhaps a nicer way of deleting all files while leaving the directory structure intact. –
Olethea Pretty intuitive way of doing it:
import shutil, os
def remove_folder_contents(path):
shutil.rmtree(path)
os.makedirs(path)
remove_folder_contents('/path/to/folder')
Other methods I tried with os and glob package, I had permission issue but with this I had no permission issue plus one less package usage. Probably fail if sub directory exist.
import os
def remove_files_in_folder(folderPath):
# loop through all the contents of folder
for filename in os.listdir(folderPath):
# remove the file
os.remove(f"{folderPath}/{filename}")
remove_files_in_folder('./src/inputFiles/tmp')
Folder structure
root
|
+-- main.py
|
+-- src
|
+-- inputFiles
|
+-- tmp
|
+-- file1.txt
+-- img1.png
Use the method bellow to remove the contents of a directory, not the directory itself:
import os
import shutil
def remove_contents(path):
for c in os.listdir(path):
full_path = os.path.join(path, c)
if os.path.isfile(full_path):
os.remove(full_path)
else:
shutil.rmtree(full_path)
If you are using the awesome PyFilesystem2 library like me, you have an out-of the box solution described in the documentation.
For example, to clear a directory Videos
under user home without removing the directory itself, use FS.removetree
combined with FS.opendir
:
import fs
home_fs = fs.open_fs("~")
home_fs.opendir("/Videos").removetree("/")
home_fs.exists("/Videos") # True
home_fs.isempty("/Videos") # True
I resolved the issue with rmtree
makedirs
by adding time.sleep()
between:
if os.path.isdir(folder_location):
shutil.rmtree(folder_location)
time.sleep(.5)
os.makedirs(folder_location, 0o777)
the easiest way to delete all files in a folder/remove all files
import os
files = os.listdir(yourFilePath)
for f in files:
os.remove(yourFilePath + f)
This should do the trick just using the OS module to list and then remove!
import os
DIR = os.list('Folder')
for i in range(len(DIR)):
os.remove('Folder'+chr(92)+i)
Worked for me, any problems let me know!
Folder
had only a sequence of files named 0
, 1
, 2
, 3
... in it, and you had a special python interpreter with a custom os.list
function in it :) –
Logomachy © 2022 - 2024 — McMap. All rights reserved.
os.system('rm -rf folder')
– Underthrustos.system('rm -rf folder/*')
is the way to go, assuming there are no.*
contents... – Propositusshutil.rmtree
(ex ignore_main_folder/preserve_main_folder). This is often useful when you don't have the user right to create the main folder. – Supplicate