ファイルを移動するには?


909

私はPython osインターフェースを調べましたが、ファイルを移動するメソッドを見つけることができませんでした。$ mv ...Pythonで同等のことをするにはどうすればよいですか?

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

1
gnu-coreutilsのmvコマンドに慣れている方のために、pythonにshutil.moveは、shutil.move機能が異なる1つのエッジケースがあります。 詳細については、こちらをご覧ください簡単に言うと、shutil.movemv宛先がディレクトリであり、そのディレクトリにソースと同じ名前のファイルがすでにある場合、Python は例外を発生させます(ただし、gnu-coreutils は発生しません)(詳細については、前の文で提供されているリンクを参照してください) )。
Trevor Boyd Smith

3
いかがos.system("mv file1 file2")ですか?
John Strood、2018年

回答:


1340

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ソースと宛先の両方の引数にファイル名()を含める必要があることに注意してください。変更されると、ファイルの名前が変更されるだけでなく、移動されます。

また、最初の2つのケースでは、新しいファイルが作成されるディレクトリがすでに存在している必要があります。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でチェックし、マックOS X.
whyisyoung

3
~はシェル構造であり、ファイルパス自体とは関係ありません。本当にホームディレクトリを使用したい場合は、os.getenv('HOME')代わりにを使用して、必要に応じて、目的のパスの一部と連結します。
2015

15
を使用os.path.expanduser()する~と、OS固有のルールに従って、 ' ' を適切に展開できます。%HOME%常にWindowsで設定されるとは限らないため、はるかにきれいです。
ig0774 2015

14
os.rename異なるデバイス間でファイルを処理しません。shutil.moveソースと宛先ファイルが同じデバイス上にあるかどうかが不明な場合に使用します。
Giuseppe Scrivano 2017年

244

けれどもos.rename()shutil.move()なり、両方の名前変更ファイル、UnixのMVコマンドに最も近いコマンドがありますshutil.move()。違いはos.rename()、ソースと宛先が異なるディスク上にある場合shutil.move()は機能しませんが、ファイルがどのディスク上にあるかは関係ありません。


75
shutil.move()os.rename()宛先が現在のファイルシステム上にある場合に使用します。それ以外の場合は、shutil.move()を使用してソースを宛先にコピーしてから、ソースをshutil.copy2()削除します。
改行

8
それが実現するように注意してくださいshutil.copy2()すべてのファイルのメタデータをコピーすることはできませんそれは、それはやってようなものだたまたまそうならば、cp -pその後、rm私は集まります。
2rs2ts 2014

9
注意:宛先がすでに存在する場合、Python 2.7.3のshutil.moveは失敗します。したがって、それが可能な場合は、エラーをキャッチするか、手動でファイル/ディレクトリを削除してから、移動してください。
ダナ

36

os.renameまたはshutil.moveの場合は、モジュールをインポートする必要があります。すべてのファイルを移動するために*文字は必要ありません。

/ opt / awesomeにsourceという名前のフォルダーがあり、awesome.txtという名前のファイルが1つあります。

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 2013年

1
宛先とソースを逆にして使用して、ファイルがソースから移動されてから元に戻ることを確認しました。
jmontross 2013年


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が複数のファイルを移動するかどうかは、OPによって明確にされていませんでした。彼は質問で1つのファイルのみを移動することについて述べましたが、彼のサンプルコードは複数のファイルを移動することを意味していました。
ジャックマシュー

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補間を使用できます。f"{new_path}{f}"ただし、文字列に静的テキストがない場合、これはより手間がかかる可能性があります。... Fストリングス。
jusopi

fの代わりにファイルを意味しますか?
Matthew
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.