How do I remove/delete a folder that is not empty with Python?
尝试删除非空文件夹时,出现"访问被拒绝"错误。我在尝试中使用了以下命令:
移除/删除非空文件夹/目录的最有效方法是什么?
1 2 3 | import shutil shutil.rmtree('/folder_name') |
标准库参考:shutil.rmtree。
根据设计,
1 | shutil.rmtree('/folder_name', ignore_errors=True) |
从
1 2 3 4 5 6 7 8 9 10 | # Delete everything reachable from the directory named in 'top', # assuming there are no symbolic links. # CAUTION: This is dangerous! For example, if top == '/', it # could delete all your disk files. import os 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)) |
1 2 | import shutil shutil.rmtree(dest, ignore_errors=True) |
从python 3.4可以使用:
1 2 3 4 5 6 7 8 9 | import pathlib def delete_folder(pth) : for sub in pth.iterdir() : if sub.is_dir() : delete_folder(sub) else : sub.unlink() pth.rmdir() # if you just want to delete dir content, remove this line |
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import os import stat import shutil def errorRemoveReadonly(func, path, exc): excvalue = exc[1] if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES: # change the file to be readable,writable,executable: 0777 os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # retry func(path) else: # raiseenter code here shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly) |
如果设置了ignore_errors,则忽略错误;否则,如果设置了onerror,则调用它以使用参数(func、path、exc_info)处理错误,其中func是os.listdir、os.remove或os.rmdir;path是导致函数失败的函数的参数;exc_info是sys.exc_info()返回的元组。如果"忽略错误"为"假",而"OnError"为"无",则会引发异常。请在此处输入代码。
只需一些python3.5选项就可以完成上面的答案。(我很想在这里找到他们)。
1 2 3 | import os import shutil from send2trash import send2trash # (shutil delete permanently) |
删除空文件夹
1 2 3 4 5 | root = r"C:\Users\Me\Desktop\test" for dir, subdirs, files in os.walk(root): if subdirs == [] and files == []: send2trash(dir) print(dir,": folder removed") |
如果文件夹包含此文件,请同时删除它
1 2 3 4 5 6 | elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file if files[0]=="desktop.ini" or: send2trash(dir) print(dir,": folder removed") else: print(dir) |
删除仅包含.srt或.txt文件的文件夹
1 2 3 4 5 6 7 8 9 | elif subdirs == []: #if dir doesn’t contains subdirectory ext = (".srt",".txt") contains_other_ext=0 for file in files: if not file.endswith(ext): contains_other_ext=True if contains_other_ext== 0: send2trash(dir) print(dir,": dir deleted") |
如果文件夹大小小于400KB,则删除该文件夹:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def get_tree_size(path): """Return total size of files in given path and subdirs.""" total = 0 for entry in os.scandir(path): if entry.is_dir(follow_symlinks=False): total += get_tree_size(entry.path) else: total += entry.stat(follow_symlinks=False).st_size return total for dir, subdirs, files in os.walk(root): If get_tree_size(dir) < 400000: # ≈ 400kb send2trash(dir) print(dir,"dir deleted") |
如果您确定要删除整个目录树,并且对目录的内容不再感兴趣,那么对整个目录树进行爬行是愚蠢的…只需从python调用本机操作系统命令即可。它将更快、更高效,而且内存消耗更少。
1 | RMDIR c:\blah /s /q |
或* nix
1 | rm -rf /home/whatever |
在Python中,代码看起来像..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import sys import os mswindows = (sys.platform =="win32") def getstatusoutput(cmd): """Return (status, output) of executing cmd in a shell.""" if not mswindows: return commands.getstatusoutput(cmd) pipe = os.popen(cmd + ' 2>&1', 'r') text = pipe.read() sts = pipe.close() if sts is None: sts = 0 if text[-1:] == ' ': text = text[:-1] return sts, text def deleteDir(path): """deletes the path entirely""" if mswindows: cmd ="RMDIR"+ path +" /s /q" else: cmd ="rm -rf"+path result = getstatusoutput(cmd) if(result[0]!=0): raise RuntimeError(result[1]) |
从docs.python.org:
This example shows how to remove a directory tree on Windows where
some of the files have their read-only bit set. It uses the onerror
callback to clear the readonly bit and reattempt the remove. Any
subsequent failure will propagate.
1
2
3
4
5
6
7
8
9 import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onerror=remove_readonly)
根据kkubasik的答案,在删除之前检查文件夹是否存在,这样更可靠。
1 2 3 4 5 6 7 8 9 10 | import shutil def remove_folder(path): # check if folder exists if os.path.exists(path): # remove if exists shutil.rmtree(path) else: # throw your exception to handle this special scenario raise XXError("your exception") remove_folder("/folder_name") |
如果您不想使用
1 2 3 4 | from os import listdir, rmdir, remove for i in listdir(directoryToRemove): os.remove(os.path.join(directoryToRemove, i)) rmdir(directoryToRemove) # Now the directory is empty of files |
1 2 3 4 5 6 7 8 9 10 11 12 13 | def deleteDir(dirPath): deleteFiles = [] deleteDirs = [] for root, dirs, files in os.walk(dirPath): for f in files: deleteFiles.append(os.path.join(root, f)) for d in dirs: deleteDirs.append(os.path.join(root, d)) for f in deleteFiles: os.remove(f) for d in deleteDirs: os.rmdir(d) os.rmdir(dirPath) |
为了简单起见,可以使用os.system命令:
1 2 | import os os.system("rm -rf dirname") |
很明显,它实际上调用系统终端来完成这个任务。
删除一个文件夹,即使它可能不存在(避免了Charles Chow的答案中的竞争条件),但当其他事情出错时仍有错误(例如权限问题、磁盘读取错误、文件不是目录)
对于Python 3 .x:
1 2 3 4 5 6 7 8 9 | import shutil def ignore_absent_file(func, path, exc_inf): except_instance = exc_inf[1] if isinstance(except_instance, FileNotFoundError): return raise except_instance shutil.rmtree(dir_to_delete, onerror=ignore_absent_file) |
python2.7代码几乎相同:
1 2 3 4 5 6 7 8 9 10 11 | import shutil import errno def ignore_absent_file(func, path, exc_inf): except_instance = exc_inf[1] if isinstance(except_instance, OSError) and \ except_instance.errno == errno.ENOENT: return raise except_instance shutil.rmtree(dir_to_delete, onerror=ignore_absent_file) |
通过os.walk,我将提出由3个一行程序python调用组成的解决方案:
1 2 3 | python -c"import sys; import os; [os.chmod(os.path.join(rs,d), 0o777) for rs,ds,fs in os.walk(_path_) for d in ds]" python -c"import sys; import os; [os.chmod(os.path.join(rs,f), 0o777) for rs,ds,fs in os.walk(_path_) for f in fs]" python -c"import os; import shutil; shutil.rmtree(_path_, ignore_errors=False)" |
第一个脚本chmod的所有子目录,第二个脚本chmod的所有文件。然后,第三个脚本会毫无障碍地删除所有内容。
我在Jenkins工作中的"shell脚本"中对此进行了测试(我不想将新的python脚本存储到SCM中,这就是为什么搜索单行解决方案),它适用于Linux和Windows。
十年后,使用python 3.7和linux仍然有不同的方法:
1 2 3 4 5 6 7 8 9 10 | import subprocess from pathlib import Path #using pathlib.Path path = Path('/path/to/your/dir') subprocess.run(["rm","-rf", str(path)]) #using strings path ="/path/to/your/dir" subprocess.run(["rm","-rf", path]) |
本质上,它使用python的子进程模块来运行bash脚本
我将
对于Windows,如果目录不是空的,并且您有只读文件,或者收到如下错误:
Access is denied The process cannot access the file because it is being used by another process
试试这个,
它相当于Linux/Mac中的
我找到了一种非常简单的方法来删除Windows操作系统上的任何文件夹(甚至不是空的)或文件。
1 | os.system('powershell.exe rmdir -r D:\workspace\Branches\*%s* -Force' %CANDIDATE_BRANCH) |