空でないフォルダを削除しようとすると、「アクセスが拒否されました」エラーが発生します。私の試みで次のコマンドを使用しました:os.remove("/folder_name")
。
空でないフォルダ/ディレクトリを削除/削除する最も効果的な方法は何ですか?
rm -rf
行動を参照してください。stackoverflow.com/questions/814167/...
空でないフォルダを削除しようとすると、「アクセスが拒否されました」エラーが発生します。私の試みで次のコマンドを使用しました:os.remove("/folder_name")
。
空でないフォルダ/ディレクトリを削除/削除する最も効果的な方法は何ですか?
rm -rf
行動を参照してください。stackoverflow.com/questions/814167/...
回答:
import shutil
shutil.rmtree('/folder_name')
設計上、rmtree
読み取り専用ファイルを含むフォルダツリーで失敗します。読み取り専用ファイルが含まれているかどうかに関係なく、フォルダーを削除する場合は、次のコマンドを使用します。
shutil.rmtree('/folder_name', ignore_errors=True)
rmtree
:読み取り専用ファイルがある場合に失敗しますstackoverflow.com/questions/2656322/...
以下からの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)
ignore_errors=True
問題を解決します。
onerror
パラメータがの代わりに使用されていますignore_errors
。このようにして、読み取り専用ファイルは無視されるのではなく削除されます。
rmtree()
メソッド全体が無視されます。
この例は、一部のファイルに読み取り専用ビットが設定されている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の場合、例外が発生します。ここにコードを入力してください
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")
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])
shutil.rmdir
、オペレーティングシステムの種類からユーザーを隔離することです。
上記の回答を完了するためのいくつかのpython 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")
if files[0]== "desktop.ini" or:
「純粋なpathlib」アプローチを追加したいと思います。
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
。したがって、ディレクトリはファイルの前に来ます。並べ替えを逆にすると、ファイルはそれぞれのコンテナの前に来るため、1つのパスで1つずつリンクを解除/ rmdirできます。
利点:
pathlib
はPython 3.6で約束されてことです。上記の操作はWindowsで実行しないと述べられていません)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)
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.remove
ディレクトリを削除できないためOsError
、directoryToRemove
サブディレクトリが含まれている場合はこれが発生します。
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])
基本的に$ rm -rf '/path/to/your/dir
は、ターミナルを使用して同じタスクを実行しているかのように、Pythonのサブプロセスモジュールを使用してbashスクリプトを実行します。それは完全にPythonではありませんが、それを実現します。
このpathlib.Path
例を含めたのは、私の経験では、変化する多くのパスを処理するときに非常に役立つためです。pathlib.Path
モジュールをインポートして最終結果を文字列に変換する追加の手順は、多くの場合、開発期間のコストを削減します。Path.rmdir()
空ではないディレクトリを明示的に処理するargオプションが付いていると便利です。
rmtree
ような隠しフォルダに関する問題に遭遇したため、このアプローチにも切り替えました.vscode
。このフォルダはテキストファイルとして検出され、エラーにより、このファイルはbusy
削除できなかったことがわかりました。
存在しない可能性がある場合でも(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)
os.walkでは、3つの1行の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のすべてのサブディレクトリ、2番目のスクリプトchmodのすべてのファイル。次に、3番目のスクリプトは、何の障害もなくすべてを削除します。
私はJenkinsジョブの「シェルスクリプト」からこれをテストしました(新しいPythonスクリプトをSCMに保存したくなかったため、1行のソリューションを検索しました)。これは、LinuxおよびWindowsで動作しました。
pathlib
、あなたは一つに最初の2つのステップを組み合わせることができます:[p.chmod(0o666) for p in pathlib.Path(_path_).glob("**/*")]
簡単にするためにos.systemコマンドを使用できます。
import os
os.system("rm -rf dirname")
明らかなように、実際にはシステムターミナルを呼び出してこのタスクを実行します。