programing

비어 있지 않은 폴더를 삭제/삭제하려면 어떻게 해야 합니까?

randomtip 2023. 1. 5. 23:59
반응형

비어 있지 않은 폴더를 삭제/삭제하려면 어떻게 해야 합니까?

비어 있지 않은 폴더를 삭제하려고 하면 '액세스가 거부되었습니다' 오류가 나타납니다.다음 명령을 사용하여 시도했습니다.os.remove("/folder_name").

비어 있지 않은 폴더/디렉토리를 삭제/삭제하는 가장 효과적인 방법은 무엇입니까?

import shutil

shutil.rmtree('/folder_name')

표준 라이브러리 레퍼런스: shutil.rmtree.

설계상rmtree읽기 전용 파일을 포함하는 폴더 트리에서 실패합니다.읽기 전용 파일이 포함되어 있는지 여부에 관계없이 폴더를 삭제하려면

shutil.rmtree('/folder_name', ignore_errors=True)

python 문서: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)

python 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 the dir content but not the dir itself, remove this line

어디에pth는 입니다.pathlib.Path사례.좋아요, 하지만 가장 빠르지 않을 수도 있어요.

의사로부터.python.org:

다음 예시는 일부 파일이 읽기 전용 비트가 설정된 윈도우즈에서 디렉터리 트리를 제거하는 방법을 보여 줍니다.온에러 콜백을 사용하여 읽기 전용 비트를 클리어하고 삭제를 재시도합니다.이후의 장애는 전파됩니다.

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이면 예외가 발생합니다.여기에 코드를 입력합니다.

Kubasik의 답변을 바탕으로 폴더가 있는지 확인하고 삭제하기 전에 보다 견고한 폴더

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

"pure pathlib" 접근 방식을 추가하고 싶습니다.

from pathlib import Path
from typing import Union

def del_dir(target: Union[Path, str], only_if_empty: bool = False):
    """
    Delete a given directory and its subdirectories.

    :param target: The directory to delete
    :param only_if_empty: Raise RuntimeError if any file is found in the tree
    """
    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()

이것은, 라는 사실에 근거하고 있다.Path긴 경로는 항상 짧은 경로 뒤에 정렬됩니다.str따라서 디렉토리가 파일보다 우선합니다.정렬을 반대로 하면 파일이 각각의 컨테이너 앞에 오므로 1개의 패스로 하나씩 링크 해제/RMDir를 할 수 있습니다.

이점:

  • 외부 바이너리에 의존하지 않습니다. 모든 것은 Python의 배터리 구동 모듈을 사용합니다(Python > = 3.6).
    • 즉, 링크 해제를 위해 새로운 서브프로세스를 반복적으로 시작할 필요가 없습니다.
  • 매우 빠르고 심플합니다.자신의 재귀를 실장할 것
  • 크로스 플랫폼입니다(적어도 그렇습니다).pathlibPython 3.6에서의 약속, Windows에서 실행되지 않도록 상기의 조작은 없습니다.)
  • 필요한 경우 삭제 시 로그 기록 등 매우 세밀한 로깅을 수행할 수 있습니다.

dir 트리 전체를 삭제하고 dir의 내용에 관심이 없다면 dir 트리 전체를 기어다니는 것은 어리석은 짓입니다.python에서 네이티브 OS 명령어를 호출하기만 하면 됩니다.고속화, 효율화, 메모리 소비량 감소.

RMDIR c:\blah /s /q 

또는 *nix

rm -rf /home/whatever 

python의 코드는 다음과 같습니다.

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

위의 답변을 완성하기 위한 몇 가지 파이썬 3.5 옵션만 있으면 됩니다.(여기서 발견했으면 좋았을 텐데)

import os
import shutil
from send2trash import send2trash # (shutil delete permanently)

비어 있는 경우 폴더 삭제

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

이 파일이 포함된 경우 폴더도 삭제

    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 파일만 포함된 경우 폴더 삭제

    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 미만인 경우 폴더 삭제:

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

10년 후에도 Python 3.7과 Linux를 사용하여 이를 수행하는 방법은 여전히 다양합니다.

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의 스크립트 "Python"을 합니다.$ rm -rf '/path/to/your/dir마치 단말기를 사용하여 동일한 작업을 수행하는 것처럼.Python은 아니지만, 할 수 있습니다.

pathlib.Path예를 들어, 제 경험상, 그것은 변화하는 많은 경로를 다룰 때 매우 유용하기 때문입니다. pathlib.Path모듈화 및 최종 결과를 문자열로 변환하는 것이 개발 시간을 단축하는 경우가 많습니다.할 것 같다Path.rmdir()에는 공백이 아닌 dir를 명시적으로 처리하기 위한 arg 옵션이 포함되어 있습니다.

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)

폴더가 존재하지 않더라도 삭제(Charles Chow의 답변에서 경쟁 조건을 피함)하지만 다른 문제가 발생했을 때 오류가 발생하는 경우(예: 권한 문제, 디스크 읽기 오류, 파일이 디렉토리가 아님)

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)

Python 2.7 코드는 거의 동일합니다.

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)

shutil에서는 모듈만 할 수 .os★★★★★★ 。

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

os.walk를 사용하면 3개의 원라이너 Python 호출로 구성된 솔루션을 제안합니다.

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 Script"에서 테스트한 결과(새로운 Python 스크립트를 SCM에 저장하고 싶지 않았기 때문에 한 줄짜리 솔루션을 검색했습니다) Linux 및 Windows에서 작동했습니다.

Windows 의 경우, 디렉토리가 비어 있지 않고, 읽기 전용 파일이 있는 경우, 또는 다음과 같은 에러가 발생하는 경우.

  • Access is denied
  • The process cannot access the file because it is being used by another process

먹어보세요.os.system('rmdir /S /Q "{}"'.format(directory))

에 상당합니다.rm -rfLinux/Mac linux linux 。

기반,, 순수, "pathlib★★★★★★★★★★★★★★★★★★:

from pathlib import Path

def remove_path(path: Path):
    if path.is_file() or path.is_symlink():
        path.unlink()
        return
    for p in path.iterdir():
        remove_path(p)
    path.rmdir()

Windows 및 심볼릭 링크 지원

os.system 명령을 사용하면 다음과 같이 간단하게 할 수 있습니다.

import os
os.system("rm -rf dirname")

이 작업을 수행하기 위해 실제로 시스템 단말기가 호출됩니다.

WINDOWS OS에서 폴더나 파일을 쉽게 삭제할 수 있는 방법을 찾았습니다.

os.system('powershell.exe  rmdir -r D:\workspace\Branches\*%s* -Force' %CANDIDATE_BRANCH)

내 경우 코드를 cmd로 실행하도록 되어 있기 때문에 모든 가능성을 이용하는 방법밖에 없었습니다.exe 또는 powershell.exe.고객님의 경우 이 코드로 함수를 생성하기만 하면 됩니다.

        #!/usr/bin/env python3

        import shutil
        from os import path, system
        import sys

        # Try to delete the folder ---------------------------------------------
        if (path.isdir(folder)):
            shutil.rmtree(folder, ignore_errors=True)

        if (path.isdir(folder)):
            try:
                system("rd -r {0}".format(folder))
            except Exception as e:
                print("WARN: Failed to delete => {0}".format(e),file=sys.stderr)

        if (path.isdir(self.backup_folder_wrk)):
            try:
                system("rd /s /q {0}".format(folder))
            except Exception as e:
                print("WARN: Failed to delete => {0}".format(e),file=sys.stderr)

        if (path.isdir(folder)):
            print("WARN: Failed to delete {0}".format(folder),file=sys.stderr)
        # -------------------------------------------------------------------------------------

파일 또는 폴더는 비어 있는지 여부에 관계없이 아래 코드를 사용하여 삭제할 수 있습니다.

import shutil
import os

directory = "path/to/the/root/folder"
files_in_directory = os.listdir(directory)

for file in files_in_directory:
    try:
        path_to_file_or_folder = os.path.join(directory, file)
        shutil.rmtree(path_to_file_or_folder)
    except:
        os.unlink(path_to_file_or_folder)

모든 파일과 폴더가 있는 디렉토리를 삭제할 수 있습니다.

import os


def rrmdir(path):
    for entry in os.scandir(path):
        if entry.is_dir():
            rrmdir(entry)
        else:
            os.remove(entry)
    os.rmdir(path)

언급URL : https://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty

반응형