파일을 옮기는 방법?


908

Python os인터페이스를 살펴 보았지만 파일을 이동하는 메소드를 찾을 수 없습니다. $ mv ...파이썬에서 어떻게 동등 합니까?

>>> source_files = '/PATH/TO/FOLDER/*'
>>> destination_folder = 'PATH/TO/FOLDER'
>>> # equivalent of $ mv source_files destination_folder

1
gnu-coreutils의 mvcommand에 익숙한 사람들을 위해 파이썬 shutil.move에는 shutil.move기능이 다른 한 가지 경우가 있습니다. 전체 쓰기를 위해 여기로 이동하십시오 . 간단히 말해서, 파이썬 shutil.movemv 목적지가 디렉토리이고 디렉토리에 이미 소스와 이름이 같은 파일이있을 때 예외를 발생시킵니다 (그러나 gnu-coreutils 는 그렇지 않습니다) (더 자세한 정보는 이전 문장에서 제공된 링크를 참조하십시오) ).
Trevor Boyd Smith

3
어때요 os.system("mv file1 file2")?
John Strood

답변:


1338

os.rename(), shutil.move()또는os.replace()

모두 동일한 구문을 사용합니다.

import os
import shutil

os.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
os.replace("path/to/current/file.foo", "path/to/new/destination/for/file.foo")

file.foo소스 및 대상 인수 모두에 파일 이름 ( )을 포함해야합니다 . 변경되면 파일 이름이 바뀌고 이동됩니다.

또한 처음 두 경우에는 새 파일이 작성되는 디렉토리가 이미 존재해야합니다. Windows에서는 해당 이름의 파일이 존재하지 않아야합니다. 그렇지 않으면 예외가 발생하지만 os.replace()해당 경우에도 파일이 자동으로 대체됩니다.

다른 답변에 대한 의견에서 언급했듯이 대부분의 경우 shutil.move전화하십시오 os.rename. 그러나 대상이 원본과 다른 디스크에 있으면 원본 파일을 복사 한 다음 삭제합니다.


8
os.rename이 디렉토리에서 작동하지 않는다고 생각하는 유일한 사람입니까? "dst가 디렉토리이면 OSError가 발생합니다."
Fabian

33
shutil.move디렉토리에서 작동합니다. shutil.move(f.name, "tmp/")shutil.move(f.name, "/Users/hello/tmp/") ~
python2.7.9

3
~쉘 구조이며, 잘못 놓인 규칙 이외의 파일 경로 자체와는 아무런 관련이 없습니다. 홈 디렉토리를 실제로 사용하려면 os.getenv('HOME')대신 필요한 경우 원하는 경로의 일부와 연결 하여 대신 사용 하십시오.
amn

15
운영 체제 별 규칙에 따라 항상 os.path.expanduser()' ~' 을 (를) 올바르게 확장하는 데 사용할 수 있습니다 . 이후 많은 깔끔한 %HOME%항상 윈도우에 설정되어 있지 않습니다.
ig0774

14
os.rename다른 장치에서 파일을 처리하지 않습니다. shutil.move소스와 대상 파일이 동일한 장치에 있는지 확실하지 않은 경우 사용하십시오 .
Giuseppe Scrivano

244

비록 os.rename()shutil.move()두 이름 바꾸기 파일 것, 유닉스 MV 명령에 가장 가까운 명령이다 shutil.move(). 차이점은 os.rename()소스와 대상이 다른 디스크에 있으면 shutil.move()작동하지 않지만 파일이있는 디스크는 신경 쓰지 않는다는 것입니다.


75
shutil.move()os.rename()대상이 현재 파일 시스템에있는 경우 사용 합니다. 그렇지 않으면을 shutil.move()사용하여 소스를 대상으로 복사 한 다음 소스를 shutil.copy2()제거합니다.
줄 바꿈

8
shutil.copy2()모든 파일 메타 데이터를 복사 할 수 없다는 점에 유의하십시오 . 그렇게된다면 그렇게 cp -p하고 나서 rm수집 하는 것과 같습니다 .
2rs2ts

9
주의 : 대상이 이미 존재하는 경우 Python 2.7.3의 shutil.move가 실패합니다. 따라서 가능하면 오류를 포착하거나 파일 / dir을 수동으로 제거한 다음 이동하십시오.
Dana

36

os.rename 또는 shutil.move의 경우 모듈을 가져와야합니다. 모든 파일을 이동시키기 위해 * 문자가 필요하지 않습니다.

/ opt / awesome에 awesome.txt라는 하나의 파일이있는 source라는 폴더가 있습니다.

in /opt/awesome
  ls
source
  ls source
awesome.txt

python 
>>> source = '/opt/awesome/source'
>>> destination = '/opt/awesome/destination'
>>> import os
>>> os.rename(source, destination)
>>> os.listdir('/opt/awesome')
['destination']

os.listdir을 사용하여 실제로 폴더 이름이 변경되었음을 확인했습니다. 목적지는 소스로 다시 이동하는 셔틀입니다.

>>> import shutil
>>> shutil.move(destination, source)
>>> os.listdir('/opt/awesome/source')
['awesome.txt']

이번에는 소스 폴더 내부에서 내가 만든 awesome.txt 파일이 있는지 확인했습니다. 저기있어 :)

이제 폴더와 파일을 소스에서 대상으로 이동했다가 다시 되돌 렸습니다.


4
docs.python.org/2/library/shutil.html 이 문서는 shutil.move 메소드에 대해 매개 변수를 전환했음을 보여줍니다.
mac10688

1
대상과 소스를 반대로 사용하여 파일이 소스에서 이동했다가 다시 되돌아 오는 것을 확인했습니다.
jmontross


14

이것이 현재 사용중인 것입니다.

import os, shutil
path = "/volume1/Users/Transfer/"
moveto = "/volume1/Users/Drive_Transfer/"
files = os.listdir(path)
files.sort()
for f in files:
    src = path+f
    dst = moveto+f
    shutil.move(src,dst)

이제 완벽하게 작동합니다. 이것이 도움이되기를 바랍니다.

편집하다:

나는 이것을 소스와 대상 디렉토리를 받아 들여 존재하지 않는 경우 대상 폴더를 만들고 파일을 이동시키는 함수로 바꿨다. 예를 들어 이미지 만 이동하려는 경우 src 파일을 필터링 할 수 있습니다. '*.jpg'기본적으로 패턴을 사용 하면 디렉토리의 모든 항목이 이동합니다

import os, shutil, pathlib, fnmatch

def move_dir(src: str, dst: str, pattern: str = '*'):
    if not os.path.isdir(dst):
        pathlib.Path(dst).mkdir(parents=True, exist_ok=True)
    for f in fnmatch.filter(os.listdir(src), pattern):
        shutil.move(os.path.join(src, f), os.path.join(dst, f))

1
fnmatch.filter ()를 사용하여 이것을 쉽게 필터링 된 이동으로 바꿀 수 있습니다. 내 편집을 참조하십시오. 또한 os.path.join(parent_path, filename)플랫폼 간 문제를 피하기 위해 문자열 연결 대신 사용하는 것이 가장 좋습니다.
iggy12345

11

질문의 답은 파일 이름을 파일로 바꾸는 것이 아니라 많은 파일을 디렉토리로 옮기는 것에 대한 것이기 때문에 대답이 맞지 않습니다. 대상은 명시적인 파일 이름을 가져야하므로이 shutil.move작업을 수행하는 os.rename데는 주석에 명시된대로 쓸모가 없습니다.


쓸모 없지는 않지만 여러 파일을 옮기려면 더 많은 작업이 필요합니다. 을 사용하여 파일 이름을 얻을 수 있고을 사용 os.path.basename(my_file_path)하여 파일 디렉토리를 얻을 수 있습니다 os.path.dirname(my_file_path). 또한 여러 파일을 이동하려는 경우 OP에 의해 명확하지 않았습니다. 그는 질문에서 하나의 파일 만 옮기는 것을 언급했지만 그의 예제 코드는 여러 파일을 옮기는 것을 암시했습니다.
Jacques Mathieu

2

여기설명 된 답변에 따라 사용 subprocess하는 또 다른 옵션입니다.

이 같은:

subprocess.call("mv %s %s" % (source_files, destination_folder), shell=True)

에 비해이 방법의 장단점을 알고 싶습니다 shutil. 내 경우에는 이미 subprocess다른 이유로 사용하고 있으며 작동하는 것처럼 보입니다.

시스템에 따라 다릅니 까?


2
나는 이것이 시스템 의존적 일 것이라고 믿는다. mvWindows 운영 체제에서 성공적으로 사용 되지 않습니다 .
Joshua Schlichting

0

이것은 가능하지 않습니다 솔루션입니다 shell사용 mv.

import subprocess

source      = 'pathToCurrent/file.foo'
destination = 'pathToNew/file.foo'

p = subprocess.Popen(['mv', source, destination], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
res = p.communicate()[0].decode('utf-8').strip()

if p.returncode:
    print 'ERROR: ' + res

-2
  import os,shutil

  current_path = "" ## source path

  new_path = "" ## destination path

  os.chdir(current_path)

  for files in os.listdir():

        os.rename(files, new_path+'{}'.format(f))
        shutil.move(files, new_path+'{}'.format(f)) ## to move files from 

다른 디스크 ex. C :-> D :


Python3. #을 사용하는 경우 새로운 f-string intrerpolation을 사용할 수 있습니다. f"{new_path}{f}"그러나 문자열에 정적 텍스트가 없으면 더 많은 작업이 필요할 수 있습니다. f- 문자열.
jusopi

f 대신에 파일을 의미합니까?
Matthew
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.