web-dev-qa-db-ja.com

Pythonでファイルを移動する方法

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

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

os.rename() または shutil.move()

どちらも同じ構文を使用します。

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")

どちらの場合も、新しいファイルが作成されるディレクトリがすでに存在している必要があります(ただし、Windowsでは、その名前のファイルが存在しないようにしないと、例外が発生します)。また、ソース引数と宛先引数の両方にファイル名(file.foo)を含める必要があります。変更された場合、ファイルは移動されるだけでなく名前も変更されます。

他の回答へのコメントで述べたように、shutil.moveはほとんどの場合単にos.renameを呼び出します。ただし、コピー先がコピー元とは異なるディスク上にある場合は、コピー元ファイルをコピーしてから削除します。

986
ig0774

os.rename()shutil.move()は両方ともファイルの名前を変更しますが、UNIXのmvコマンドに最も近いコマンドはshutil.move()です。違いは、コピー元とコピー先が異なるディスク上にある場合はos.rename()は機能しないのに対し、shutil.move()はファイルがどのディスク上にあるかは関係ないということです。

215
Jim Calfas

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を使用しました。これは目的地をソースに戻すshutilです。

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

今回は、作成したawesome.txtファイルが存在することを確認するために、ソースフォルダ内をチェックしました。それはあります:)

これで、フォルダとそのファイルを移動元から移動先に移動し、また元に戻しました。

31
jmontross

問題は、ファイルの名前をファイルに変更するのではなく、多くのファイルをディレクトリに移動することであるため、受け入れられた答えは正しいものではありません。 destinationは明示的なファイル名を持たなければならないので、shutil.moveは仕事をしますが、この目的のためにos.renameは役に立ちません(コメントで述べたように)。

10
Javier Palacios

これは私が現在使用しているものです:

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))
9
Peter Vlaar

Python 3.4以降は、pathlibのクラスPathを使ってファイルを移動することもできます。

Path("path/to/current/file.foo").rename("path/to/new/destination/for/file.foo")

https://docs.python.org/3.4/library/pathlib.html#pathlib.Path.rename

7
MoonFruit

ここに記述されている に基づいて、subprocessを使うことは別の選択肢です。

このようなもの:

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

私はこのメソッドの長所と短所をshutilと比較して知りたいと思います。私の場合私は他の理由で既にsubprocessを使っていて、うまくいくように思われるので私はそれに固執する傾向があります。

それはおそらくシステムに依存しますか?

1
Bill

これは解決策で、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
0
alper