비어 있지 않은 폴더를 제거 / 삭제하려면 어떻게합니까?
비어 있지 않은 폴더를 삭제하려고하면 '액세스가 거부되었습니다'오류가 발생합니다. 내 시도에서 다음 명령을 사용했습니다 os.remove("/folder_name")
..
비어 있지 않은 폴더 / 디렉토리를 제거 / 삭제하는 가장 효과적인 방법은 무엇입니까?
import shutil
shutil.rmtree('/folder_name')
의도적으로 rmtree
읽기 전용 파일이 포함 된 폴더 트리 에서 실패합니다. 읽기 전용 파일이 있는지 여부에 관계없이 폴더를 삭제하려면 다음을 사용하십시오.
shutil.rmtree('/folder_name', ignore_errors=True)
에서 파이썬 문서 에 os.walk()
:
# 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))
import shutil
shutil.rmtree(dest, ignore_errors=True)
파이썬 3.4에서 다음을 사용할 수 있습니다.
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
인스턴스 pth
는 어디에 있습니까 pathlib.Path
? 좋지만 가장 빠르지는 않을 수 있습니다.
에서 docs.python.org :
이 예는 일부 파일에 읽기 전용 비트 세트가있는 Windows에서 디렉토리 트리를 제거하는 방법을 보여줍니다. onerror 콜백을 사용하여 읽기 전용 비트를 지우고 제거를 다시 시도합니다. 후속 실패는 전파됩니다.
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)
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 ()에 의해 반환 된 튜플입니다. ignore_errors가 false이고 onerror가 None이면 예외가 발생합니다. 여기에 코드를 입력하십시오.
if you are sure, that you want to delete the entire dir tree, and are no more interested in contents of dir, then crawling for entire dir tree is stupidness... just call native OS command from python to do that. It will be faster, efficient and less memory consuming.
RMDIR c:\blah /s /q
or *nix
rm -rf /home/whatever
In python, the code will look like..
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:] == '\n': 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])
Just some python 3.5 options to complete the answers above. (I would have loved to find them here).
import os
import shutil
from send2trash import send2trash # (shutil delete permanently)
Delete folder if empty
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")
Delete also folder if it contains this file
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)
delete folder if it contains only .srt or .txt file(s)
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")
Delete folder if its size is less than 400kb :
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")
Base on kkubasik's answer, check if folder exists before remove, more robust
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")
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)
If you don't want to use the shutil
module you can just use the os
module.
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
You can use os.system command for simplicity:
import os
os.system("rm -rf dirname")
As obvious, it actually invokes system terminal to accomplish this task.
To delete a folder even if it might not exist (avoiding the race condition in Charles Chow's answer) but still have errors when other things go wrong (e.g. permission problems, disk read error, the file isn't a directory)
For Python 3.x:
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)
The Python 2.7 code is almost the same:
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)
With os.walk I would propose the solution which consists of 3 one-liner Python calls:
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)"
The first script chmod's all sub-directories, the second script chmod's all files. Then the third script removes everything with no impediments.
I have tested this from the "Shell Script" in a Jenkins job (I did not want to store a new Python script into SCM, that's why searched for a one-line solution) and it worked for Linux and Windows.
Ten years later and using Python 3.7 and Linux there are still different ways to do this:
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])
Essentially it's using Python's subprocess module to run the bash script $ rm -rf '/path/to/your/dir
as if you were using the terminal to accomplish the same task. It's not fully Python, but it gets it done.
The reason I included the pathlib.Path
example is because in my experience it's very useful when dealing with many paths that change. The extra steps of importing the pathlib.Path
module and converting the end results to strings is often a lower cost to me for development time. It would be convenient if Path.rmdir()
came with an arg option to explicitly handle non-empty dirs.
I'd like to add a "pure pathlib" approach:
from pathlib import Path
from typing import Union
def del_dir(target: Union[Path, str], only_if_empty: bool = False):
target = Path(target).expanduser()
assert target.is_dir()
for p in sorted(target.glob('**/*'), reverse=True):
if not p.exists():
continue
p.chmod(0o666)
if p.is_dir():
p.rmdir()
else:
if only_if_empty:
raise RuntimeError(f'{p.parent} is not empty!')
p.unlink()
target.rmdir()
This relies on the fact that Path
is orderable, and longer paths will always sort after shorter paths, just like str
. Therefore, directories will come before files. If we reverse the sort, files will then come before their respective containers, so we can simply unlink/rmdir them one by one with one pass.
Benefits:
- It's NOT relying on external binaries: everything uses Python's batteries-included modules (Python >= 3.6)
- It's fast and memory-efficient: No recursion stack, no need to start a subprocess
- It's cross-platform (at least, that's what
pathlib
promises in Python 3.6; no operation above stated to not run on Windows) - If needed, one can do a very granular logging, e.g., log each deletion as it happens.
I have found a very easy way to Delete any folder(Even NOT Empty) or file on WINDOWS OS.
os.system('powershell.exe rmdir -r D:\workspace\Branches\*%s* -Force' %CANDIDATE_BRANCH)
For Windows, if directory is not empty, and you have read-only files or you get errors like
Access is denied
The process cannot access the file because it is being used by another process
Try this, os.system('rmdir /S /Q "{}"'.format(directory))
It's equivalent for rm -rf
in Linux/Mac.
참고URL : https://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty
'code' 카테고리의 다른 글
픽셀을 dp로 변환 (0) | 2020.09.29 |
---|---|
Java에서 SoftReference와 WeakReference의 차이점은 무엇입니까? (0) | 2020.09.29 |
글로벌 Git 무시 (0) | 2020.09.29 |
Java "Double Brace Initialization"의 효율성? (0) | 2020.09.29 |
{this.props.children}에 소품을 전달하는 방법 (0) | 2020.09.29 |