जो फ़ोल्डर खाली नहीं है, मैं उसे कैसे हटा / हटाऊं?


846

जब मैं खाली नहीं होने वाले फ़ोल्डर को हटाने का प्रयास करता हूं, तो मुझे 'पहुंच अस्वीकृत' त्रुटि मिल रही है। मैं अपने प्रयास में निम्न आदेश का प्रयोग किया: os.remove("/folder_name")

एक फ़ोल्डर / निर्देशिका को हटाने / हटाने का सबसे प्रभावी तरीका क्या है जो खाली नहीं है?


32
यह भी ध्यान दें कि यदि निर्देशिका खाली थी, तो os.remove फिर से विफल हो जाएगा, क्योंकि सही फ़ंक्शन os.rmdir है।
22

और विशिष्ट rm -rfव्यवहार के लिए देखें: stackoverflow.com/questions/814167/…
Ciro Santilli 审查::: ''

जवाबों:


1345
import shutil

shutil.rmtree('/folder_name')

मानक पुस्तकालय संदर्भ: shutil.rmtree

डिज़ाइन द्वारा, rmtreeकेवल-पढ़ने वाली फ़ाइलों वाले फ़ोल्डर पेड़ों पर विफल रहता है। यदि आप चाहते हैं कि फ़ोल्डर को हटा दिया जाए, चाहे उसमें केवल-पढ़ने के लिए फ़ाइलें हों, तो उपयोग करें

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

73
ध्यान दें कि rmtreeयदि केवल-पढ़ने वाली फ़ाइलें हैं तो विफल हो जाएगी: stackoverflow.com/questions/2656322/…
श्रीधर रत्नाकुमार

9
यह मेरे लिए काम नहीं करता है: ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "foo.py", पंक्ति 31, में <मॉड्यूल> shutil.rmtree (thistestdir) फ़ाइल "/usr/lib/pythonj.6/shutil.py ", rmtree onerror (os.rmdir, path, sys.exc_info ()) फ़ाइल" /usr/lib/python2.6/shutil.py ", line3 में rmtree os.rmdir (path) OSError: लाइन 225, [Errno 90] निर्देशिका खाली नहीं: '/ पथ / से / rmtree'
क्लेटन ह्यूजेस

4
क्लेटन: सभी संभावना में, एक फ़ाइल को समवर्ती रूप से जोड़ा गया था, जबकि rmtree सामान हटाने में व्यस्त था, "rm -rf" वही विफल हो जाएगा।
दादा

13
किसी को पता है कि यह कार्यक्षमता ओएस पैकेज में क्यों नहीं है? Os.rmdir की तरह लगता है काफी बेकार है। इस तरह से इसे लागू करने के लिए कोई अच्छा तर्क क्यों?
मैल्कम

21
@ माल्कम पैकेज ओएस कार्यों के लिए एक आवरण है। पर POSIX सिस्टम rmdir असफल जाएगा, यदि निर्देशिका खाली नहीं है। उबंटू और विंडोज इस संबंध में POSIX- अनुपालन के लोकप्रिय उदाहरण हैं।
इयान सैमुअल मैकलीन एल्डर

138

से अजगर डॉक्स पर 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))

1
खैर, शायद मैं नीच का गलत हूँ। लेकिन मैं कर सकता हूँ, अभी मुझे लगता है कि यह सही है।
दादा

3
@ डीडीए: शॉल का उपयोग करते समय निश्चित रूप से सबसे आसान तरीका है, इस समाधान के बारे में निश्चित रूप से कुछ भी नहीं है। मैंने इस उत्तर को नहीं दिया है, लेकिन मेरे पास इस समय केवल आपके डाउनवोट को रद्द करने का है :)
जेरेमी कैंटरेल

7
कोड ही पाइथोनिक है। एक वास्तविक कार्यक्रम में shutil.rmtree के बजाय इसका उपयोग करना unpythonic होगा: जो "इसे करने के एक स्पष्ट तरीके" को अनदेखा कर रहा होगा। वैसे भी, यह शब्दार्थ है, downmod को दूर करना।
दादा

2
@ddaa क्या हर फाइल को डिलीट करना है या डिलीट करना चाहते हैं? मुझे यकीन नहीं है कि shutil.rmtree के साथ कैसे करें?
जोनाथन कोमार

4
@ दादा यह विचार के लिए भोजन था यानी बयानबाजी। मैं जानता हूँ मैं क्या कर रहा हूँ। मैंने सोचा था कि आप एक ऐसा कारण बताकर "इसे करने के स्पष्ट तरीके" पर पुनर्विचार करना पसंद कर सकते हैं, इसलिए शील.श्री सही "फिट" नहीं हो सकता है।
जोनाथन कोमार

112
import shutil
shutil.rmtree(dest, ignore_errors=True)

1
यह सही जवाब है। मेरे सिस्टम में, भले ही मैंने लिखने-पढ़ने के लिए विशेष फ़ोल्डर में सब कुछ सेट किया हो, जब मैं हटाने की कोशिश करता हूं तो मुझे एक त्रुटि मिलती है। ignore_errors=Trueसमस्या हल करता है।
Aventinus

3
मेरे जवाब में onerrorइसके बजाय पैरामीटर का उपयोग किया जाता है ignore_errors। इस तरह से रीड-ओनली फाइलें नजरअंदाज करने के बजाय डिलीट हो जाती हैं।
डेव चैंडलर

हां, यह त्रुटि पर फ़ाइलों को नहीं हटाएगा। तो मूल रूप से पूरी rmtree()विधि की उपेक्षा की जाती है।
जूहा अनटाइनन

1
यह 6 साल पहले स्वीकार किए गए उत्तर के लिए एक छोटा सा संपादन होना चाहिए था, बल्कि एक नया उत्तर था। अब मैं यह करूँगा।
जीन-फ्रांकोइस कॉर्बेट

22

अजगर 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उदाहरण है। अच्छा है, लेकिन सबसे तेज नहीं हो सकता।


10

से docs.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)

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

अगर ign_errors सेट है, तो त्रुटियों को अनदेखा किया जाता है; अन्यथा, यदि ऑनरोर सेट किया गया है, तो इसे तर्कों के साथ त्रुटि को संभालने के लिए कहा जाता है (func, path, exc_info) जहां func os.listdir, os.remove, या os.rmdir है; पथ उस फ़ंक्शन का तर्क है जिसके कारण वह विफल हो गया; और exc_info tysle sys.exc_info () द्वारा लौटाया गया है। अगर ign_errors गलत है और onerror कोई नहीं है, तो एक अपवाद उठाया गया है


डॉक्स के अनुसार , ऑनरोर द्वारा उठाए गए अपवादों को नहीं पकड़ा जाएगा, इसलिए मुझे यकीन नहीं है कि आपका बढ़ा हुआ प्रवेश कोड यहां कुछ भी है।
16

-1। डेव चैंडलर के जवाब की तुलना में यह अधूरा लगता है। इसके अलावा, यदि हम आसानी से निकालना चाहते हैं, तो हमें फ़ाइलों को निष्पादन योग्य बनाने की आवश्यकता नहीं है।
इडबरी

7

Kkubasik के उत्तर के आधार पर, जांचें कि क्या फ़ोल्डर हटाने से पहले मौजूद है, अधिक मजबूत

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

6
यह एक संभावित दौड़ की स्थिति का परिचय देता है
कोरी गोल्डबर्ग

1
के अनुसार सबसे ज्यादा pythonic तरह से करने के लिए हटाना एक फ़ाइल जो-मई-नहीं-अस्तित्व है, यह करने के लिए प्राथमिकता दी जाती है tryको हटाने और संभाल exceptकॉल की तुलना मेंexists() पहले
TT--

6

यदि आप सुनिश्चित हैं, कि आप संपूर्ण dir वृक्ष को हटाना चाहते हैं, और dir की सामग्री में कोई अधिक दिलचस्पी नहीं है, तो पूरे dir वृक्ष के लिए रेंगना बेवकूफी है ... बस ऐसा करने के लिए अजगर से देशी OS कमांड को कॉल करें। यह तेज, कुशल और कम मेमोरी वाला होगा।

RMDIR c:\blah /s /q 

या * निक्स

rm -rf /home/whatever 

अजगर में, कोड की तरह दिखेगा ..

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

33
-1। उपयोग shutil.rmdirकरने का पूरा बिंदु आपको ऑपरेटिंग सिस्टम के प्रकार से इन्सुलेट करना है।
mtrw

3
मैं अवधारणा को समझता हूं, लेकिन जब कोई इस तथ्य के बारे में अच्छी तरह से जानता है कि वह फ़ोल्डर को पूरी तरह से हटाना चाहता है, तो पूरी फ़ाइल ट्री को क्रॉल करने का क्या मतलब है? shutil.rmdir विशेष रूप से os.listdir (), os.path.islink () आदि आदि को कॉल करता है। कुछ चेक जो वास्तव में हमेशा आवश्यक नहीं होते हैं, जैसा कि सभी आवश्यक है फ़ाइल सिस्टम नोड को अनलिंक करने के लिए। MSAuto / WinCE विकास के लिए MSWindows की तरह कुछ बिल्ड सिस्टमों के पास, फिर shtuil.rmdir लगभग हमेशा विफल हो जाएगा, क्योंकि MSAuto बैच आधारित विकास कुछ असफल असफलता पर फ़ाइलों का निर्माण करता है, और केवल rmdir / S / Q या पुनरारंभ साफ़ करने के लिए सहायक होता है उन्हें।
PM

2
हाँ, बस आरएम कर्नेल के करीब है, कम समय, मेमोरी और सीपीयू का उपयोग करते हुए ..... और जैसा कि मैंने कहा, मेरे लिए इस पद्धति का उपयोग करने का कारण MSAuto बैच द्वारा बनाई गई ताले के पीछे था क्योंकि स्क्रिप्ट का निर्माण ...
पीएम

3
हां, लेकिन शटील का उपयोग करने से कोड क्रॉस-प्लेटफॉर्म बन जाता है और प्लेटफॉर्म विवरण दूर हो जाता है।
xshoppyx

2
मुझे नहीं लगता कि इस उत्तर को 1 से नीचे वोट दिया जाना चाहिए क्योंकि यह कुछ स्थितियों के लिए एक काम के लिए एक बहुत अच्छा संदर्भ प्रदान करता है जिसमें एक पाठक को दिलचस्पी हो सकती है। मुझे उनके साथ क्रम में रैंक किए गए कई तरीकों का आनंद लेना चाहिए। इसलिए भले ही मुझे इसका उपयोग करने की आवश्यकता नहीं है लेकिन मुझे पता है कि यह किया जा सकता है और कैसे।
kmcguire

5

उपरोक्त उत्तरों को पूरा करने के लिए बस कुछ अजगर 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")

4
कृपया if files[0]== "desktop.ini" or:
इंडेंटेटियन

5

मैं "शुद्ध पाथलिब" दृष्टिकोण जोड़ना चाहता हूं:

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

यह इस तथ्य पर निर्भर करता है कि Pathऑर्डर करने योग्य है, और लंबे रास्ते हमेशा की तरह छोटे रास्ते के बाद छंटेंगे str। इसलिए, फ़ाइलों से पहले निर्देशिकाएं आएंगी। अगर हम उलटे सॉर्ट को करते हैं, तो फाइलें उनके संबंधित कंटेनरों से पहले आ जाएंगी, इसलिए हम उन्हें एक-एक करके एक-एक पास दे सकते हैं।

लाभ:

  • यह बाहरी बायनेरिज़ पर निर्भर नहीं है: सब कुछ पाइथन की बैटरी-शामिल मॉड्यूल (पायथन> = 3.6) का उपयोग करता है
  • यह तेज़ और मेमोरी-कुशल है: कोई रिकर्सन स्टैक नहीं, सबप्रोसेस शुरू करने की आवश्यकता नहीं
  • यह क्रॉस-प्लेटफ़ॉर्म है (कम से कम, यही है pathlib पैथॉन 3.6 में वादा किया गया है; ऊपर कोई ऑपरेशन विंडोज पर नहीं चलने के लिए कहा गया है)
  • यदि आवश्यक हो, तो एक बहुत दानेदार लॉगिंग कर सकता है, उदाहरण के लिए, प्रत्येक विलोपन को लॉग करें जैसा कि होता है।

क्या आप भी एक उदाहरण उदाहरण प्रदान कर सकते हैं। del_dir (पथ ())? धन्यवाद
बजे -'१ l

@lcapra बस इसे पहले आर्ग के रूप में हटाने के लिए निर्देशिका के साथ कॉल करें।
पेपोलुआन

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

स्क्रिप्ट बनाने के लिए बढ़िया है जो उन्हें आँख बंद करके हटाने से पहले फ़ाइल को क्वारेंटीन में रखता है।
रेवरियोबीरो

3

यदि आप 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

2
os.removeनिर्देशिकाओं को हटा नहीं सकते हैं, इसलिए OsErrorयदि directoryToRemoveउपनिर्देशिकाएँ होंगी तो यह बढ़ेगी ।
नामस्रोत

#प्रोनोरेट्रेसकांड
कप्पड

3

दस साल बाद और पायथन 3.7 और लिनक्स का उपयोग करने के लिए अभी भी अलग-अलग तरीके हैं।

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

मूल रूप से यह बिश स्क्रिप्ट को चलाने के लिए पायथन के सबप्रोसेस मॉड्यूल का उपयोग कर रहा है $ rm -rf '/path/to/your/dirजैसे कि आप उसी कार्य को पूरा करने के लिए टर्मिनल का उपयोग कर रहे थे। यह पूरी तरह से पायथन नहीं है, लेकिन इसे पूरा किया जाता है।

मैंने जो pathlib.Pathउदाहरण प्रस्तुत किया, उसका कारण यह है कि मेरे अनुभव में यह बहुत उपयोगी है कि कई रास्तों के साथ काम किया जाए। pathlib.Pathमॉड्यूल को आयात करने और अंतिम परिणामों को स्ट्रिंग्स में परिवर्तित करने के अतिरिक्त कदम अक्सर विकास के समय के लिए मेरे लिए एक कम लागत है। Path.rmdir()गैर-रिक्त डायरियों को स्पष्ट रूप से संभालने के लिए एक arg विकल्प के साथ आने पर यह सुविधाजनक होगा ।


मैंने इस दृष्टिकोण पर भी स्विच किया, क्योंकि मैं rmtreeजैसे और छिपे हुए फ़ोल्डरों के साथ समस्याओं में भाग गया था .vscode। इस फ़ोल्डर को टेक्स्ट-फाइल के रूप में पाया गया और त्रुटि ने मुझे बताया कि यह फ़ाइल थी busyऔर इसे हटाया नहीं जा सकता था ।
डैनियल ईसेनरिच

2

एक फ़ोल्डर को हटाने के लिए भले ही यह मौजूद न हो (दौड़ की स्थिति से बचने में) चार्ल्स चाउ के जवाब ), लेकिन अभी भी त्रुटियां हैं जब अन्य चीजें गलत हो जाती हैं (जैसे अनुमति समस्याएं, डिस्क रीड त्रुटि, फ़ाइल निर्देशिका नहीं है)

पायथन 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)

पायथन 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)

1

Os.walk के साथ मैं उस समाधान का प्रस्ताव रखूंगा जिसमें 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 की सभी फाइलें। फिर तीसरी स्क्रिप्ट बिना किसी बाधा के सब कुछ हटा देती है।

मैंने जेनकिन्स की नौकरी में "शेल स्क्रिप्ट" से इसका परीक्षण किया है (मैं एक नई पायथन स्क्रिप्ट को एससीएम में संग्रहीत नहीं करना चाहता था, इसीलिए एक-लाइन समाधान के लिए खोज की गई) और इसने लिनक्स और विंडोज के लिए काम किया।


इसके साथ pathlib, आप पहले दो चरणों को एक में जोड़ सकते हैं:[p.chmod(0o666) for p in pathlib.Path(_path_).glob("**/*")]
पेपोलुआन

0

आप सादगी के लिए os.system कमांड का उपयोग कर सकते हैं:

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

स्पष्ट रूप से, यह वास्तव में इस कार्य को पूरा करने के लिए सिस्टम टर्मिनल को आमंत्रित करता है।


19
क्षमा करें, यह Unpythonic और प्लेटफ़ॉर्म आश्रित है।
अमी तेवरी

0

मैंने किसी भी फ़ोल्डर (यहां तक ​​कि खाली नहीं) या WINDOWS OS पर फ़ाइल को हटाने का एक बहुत ही आसान तरीका खोजा है ।

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

0

विंडोज के लिए, यदि निर्देशिका खाली नहीं है, और आपके पास केवल-पढ़ने वाली फाइलें हैं या आपको त्रुटियां मिलती हैं

  • 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 -rfलिनक्स / मैक के लिए बराबर है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.