bar
하나 이상의 파일 을 포함하는 디렉토리 와 하나 이상의 파일 을 포함하는 디렉토리를 포함하는 디렉토리에서 다음 코드를 실행하십시오 baz
. 라는 디렉토리가 없는지 확인하십시오 foo
.
import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo')
다음과 같이 실패합니다.
$ python copytree_test.py
Traceback (most recent call last):
File "copytree_test.py", line 5, in <module>
shutil.copytree('baz', 'foo')
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/shutil.py", line 110, in copytree
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/os.py", line 172, in makedirs
OSError: [Errno 17] File exists: 'foo'
나는 마치 타이핑 한 것과 같은 방식으로 작동하기를 원합니다.
$ mkdir foo
$ cp bar/* foo/
$ cp baz/* foo/
내가 사용해야하는 shutil.copy()
각각의 파일을 복사 baz
에 foo
? (이미 ‘bar’의 내용을 ‘ shutil.copytree()
? ‘를 사용하여 ‘foo’에 복사 한 후 ) 더 쉬운 방법이 있습니까?
답변
이 표준의 한계는 shutil.copytree
자의적이고 성가신 것 같습니다. 해결 방법 :
import os, shutil
def copytree(src, dst, symlinks=False, ignore=None):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
표준과 완전히 일치하지는 않습니다 copytree
.
- 트리 의 루트 디렉토리에 대한 매개 변수
symlinks
와ignore
매개 변수를 존중하지 않습니다src
. shutil.Error
루트 수준에서 오류가 발생 하지 않습니다src
.- 서브 트리 복사 중 오류가 발생하면
shutil.Error
다른 서브 트리를 복사하려고 시도하고 단일 결합을 발생시키는 대신 해당 서브 트리에 대해 발생shutil.Error
합니다.
답변
표준 라이브러리의 일부인 솔루션은 다음과 같습니다.
from distutils.dir_util import copy_tree
copy_tree("/a/b/c", "/x/y/z")
이 비슷한 질문을보십시오.
답변
위 함수가 항상 소스에서 대상으로 파일을 복사하려고하는 함수에 대한 atzz의 대답이 약간 개선되었습니다.
def copytree(src, dst, symlinks=False, ignore=None):
if not os.path.exists(dst):
os.makedirs(dst)
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
copytree(s, d, symlinks, ignore)
else:
if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
shutil.copy2(s, d)
위의 구현에서
- 존재하지 않는 경우 출력 디렉토리 작성
- 내 자신의 메소드를 재귀 적으로 호출하여 복사 디렉토리 수행
- 실제로 파일을 복사 할 때 파일이 수정되었는지 확인한 다음 복사해야합니다.
scons 빌드와 함께 위의 기능을 사용하고 있습니다. 컴파일 할 때마다 전체 파일 세트를 복사 할 필요는 없지만 수정 된 파일 만 복사하면 도움이되었습니다.
답변
atzz와 Mital Vora에서 영감을 얻은 병합 :
#!/usr/bin/python
import os
import shutil
import stat
def copytree(src, dst, symlinks = False, ignore = None):
if not os.path.exists(dst):
os.makedirs(dst)
shutil.copystat(src, dst)
lst = os.listdir(src)
if ignore:
excl = ignore(src, lst)
lst = [x for x in lst if x not in excl]
for item in lst:
s = os.path.join(src, item)
d = os.path.join(dst, item)
if symlinks and os.path.islink(s):
if os.path.lexists(d):
os.remove(d)
os.symlink(os.readlink(s), d)
try:
st = os.lstat(s)
mode = stat.S_IMODE(st.st_mode)
os.lchmod(d, mode)
except:
pass # lchmod not available
elif os.path.isdir(s):
copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
- 동일 행동 shutil.copytree 와, 심볼릭 링크 와 무시 매개 변수를
- 존재하지 않는 경우 디렉토리 대상 구조 작성
- dst가 이미 존재 하면 실패하지 않습니다
답변
파이썬 3.8은 다음과 같은 dirs_exist_ok
주장 을 소개 했습니다 shutil.copytree
.
src 를 루트로하는 전체 디렉토리 트리를 dst 라는 디렉토리에 재귀 적으로 복사 하고 대상 디렉토리를 리턴하십시오. dirs_exist_ok 는 dst 또는 누락 된 상위 디렉토리가 이미 존재하는 경우 예외를 발생 시킬지 여부를 나타냅니다 .
따라서 Python 3.8 이상에서는 다음과 같이 작동합니다.
import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo', dirs_exist_ok=True)
답변
docs는 대상 디렉토리가 존재 하지 않아야 함을 명시 적으로 나타냅니다 .
로 이름이 지정된 대상 디렉토리가
dst
아직 존재하지 않아야합니다. 상위 디렉토리가 누락 될뿐만 아니라 작성됩니다.
가장 좋은 방법은 os.walk
두 번째 및 모든 후속 디렉토리, copy2
디렉토리 및 파일에 대한 것이며 copystat
디렉토리에 추가 작업을 수행하는 것 입니다. 결국 그것은 copytree
문서에 설명 된 것과 정확히 일치합니다 . 또는 당신은 할 수 copy
및 copystat
각 디렉토리 / 파일 os.listdir
대신 os.walk
.
답변
이것은 atzz가 제공 한 원래의 최고의 답변에서 영감을 얻었습니다. 바로 파일 / 폴더 논리 바꾸기를 추가했습니다. 따라서 실제로 병합되지 않지만 기존 파일 / 폴더를 삭제하고 새 파일 / 폴더를 복사합니다.
import shutil
import os
def copytree(src, dst, symlinks=False, ignore=None):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.exists(d):
try:
shutil.rmtree(d)
except Exception as e:
print e
os.unlink(d)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
#shutil.rmtree(src)
rmtree의 주석 처리를 제거하여 이동 기능으로 만드십시오.