![](/img/trans.png)
[英]How to recursively copy all files with a certain extension in a directory using Python?
[英]How to copy directory recursively in python and overwrite all?
我正在嘗試將/home/myUser/dir1/
及其所有內容(及其內容等)復制到 python 中的/home/myuser/dir2/
。 此外,我希望副本覆蓋dir2/
中的所有內容。
看起來distutils.dir_util.copy_tree
可能是完成這項工作的正確工具,但不確定是否有更容易/更明顯的東西可以用於這樣一個簡單的任務。
如果它是正確的工具,我該如何使用它? 根據文檔,它需要 8 個參數。 我是否必須通過所有 8 個,只是src
、 dst
和update
,如果是,如何(我是 Python 的新手)。
如果有更好的東西,有人可以給我一個例子並指出正確的方向嗎?
您可以使用distutils.dir_util.copy_tree
。 它工作得很好,您不必傳遞每個參數,只有src
和dst
是強制性的。
但是,在您的情況下,您不能使用類似shutil.copytree
類的工具,因為它的行為不同:因為目標目錄必須不存在,因此該函數不能用於覆蓋其內容。
如果您想按照問題注釋中的建議使用cp
工具,請注意使用subprocess
模塊是當前推薦的生成新進程的方法,如您在 os.system 函數的文檔中所見。
看看shutil
包,尤其是rmtree
和copytree
。 您可以使用os.paths.exists(<path>)
檢查文件/路徑是否存在。
import shutil
import os
def copy_and_overwrite(from_path, to_path):
if os.path.exists(to_path):
shutil.rmtree(to_path)
shutil.copytree(from_path, to_path)
如果目錄已經存在,文森特關於copytree
是正確的。 所以distutils
是更好的版本。 以下是shutil.copytree
的固定版本。 它基本上是 1-1 復制的,除了第一個os.makedirs()
放在 if-else-construct 后面:
import os
from shutil import *
def copytree(src, dst, symlinks=False, ignore=None):
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
if not os.path.isdir(dst): # This one line does the trick
os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else:
# Will raise a SpecialFileError for unsupported file types
copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error, err:
errors.extend(err.args[0])
except EnvironmentError, why:
errors.append((srcname, dstname, str(why)))
try:
copystat(src, dst)
except OSError, why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
else:
errors.extend((src, dst, str(why)))
if errors:
raise Error, errors
這是一個簡單的解決方案,可以使用源遞歸覆蓋目標,並在執行過程中創建任何必要的目錄。 這不處理符號鏈接,但它是一個簡單的擴展(參見上面@Michael 的回答)。
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
if ignore is not None:
ignored = ignore(src, files)
else:
ignored = set()
for f in files:
if f not in ignored:
recursive_overwrite(os.path.join(src, f),
os.path.join(dest, f),
ignore)
else:
shutil.copyfile(src, dest)
在 Python 3.8 中, dirs_exist_ok
關鍵字參數被添加到shutil.copytree()
:
dirs_exist_ok
指示是否在dst
或任何丟失的父目錄已經存在的情況下引發異常。
因此,即使目標目錄已經存在,以下內容也適用於最新版本的 Python:
shutil.copytree(src, dest, dirs_exist_ok=True) # 3.8+ only!
一個主要的好處是它比distutils.dir_util.copy_tree()
更靈活,因為它需要忽略文件的其他參數等(請參閱文檔)。 最重要的是,已接受的PEP 632還指出distutils
將被棄用,隨后在 Python 3 的未來版本中將被刪除。
我的簡單回答。
def get_files_tree(src="src_path"):
req_files = []
for r, d, files in os.walk(src):
for file in files:
src_file = os.path.join(r, file)
src_file = src_file.replace('\\', '/')
if src_file.endswith('.db'):
continue
req_files.append(src_file)
return req_files
def copy_tree_force(src_path="",dest_path=""):
"""
make sure that all the paths has correct slash characters.
"""
for cf in get_files_tree(src=src_path):
df= cf.replace(src_path, dest_path)
if not os.path.exists(os.path.dirname(df)):
os.makedirs(os.path.dirname(df))
shutil.copy2(cf, df)
shutil.copytree() 已更新。 您可以添加以下參數:
shutil.copytree(src, dst, dirs_exist_ok=True)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.