[解決!Python]ファイルやディレクトリを名前変更/移動するには:shutilモジュール編解決!Python

shutilモジュールが提供するmove関数を使って、ファイルやディレクトリの名前を変更したり、移動したりする方法を紹介する。

» 2022年07月26日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

import shutil
from pathlib import Path

foo = Path('foo.txt')
bar = Path('bar.txt')

foo.touch()  # 準備としてファイルを作成
bar.touch()  # 同上

# ファイルの名前変更
res = shutil.move('foo.txt', 'baz.txt')
print(res)  # baz.txt:戻り値は変更後(移動後)の名前

# 既存のファイルの名前を指定
res = shutil.move('bar.txt', 'baz.txt'# UNIX:OK、Windows:OK
print(res)  # baz.txt

# 既存のディレクトリの名前を指定するとファイルの移動になる
dir1 = Path('dir1')
dir1.mkdir()
res = shutil.move('baz.txt', 'dir1')
print(res)  # dir1/baz.txt

# 移動先として存在しないファイルの名前を指定
dir2 = Path('dir2')
dir2.mkdir()
res = shutil.move('dir1/baz.txt', 'dir2/qux.txt')
print(res)  # dir2/qux.txt

# 存在しないディレクトリが含まれているパスを移動先に指定すると例外
shutil.move('dir2/qux.txt', 'dir3/quux.txt'# FileNotFoundError

# ディレクトリの名前変更
res = shutil.move('dir1', 'dir3')
print(res)  # dir3

# 既存ファイルの名前をdestに指定するとFileExistsError例外
shutil.move('dir3', 'dir2/qux.txt'# FileExistsError

# 変更後の名前として既存のディレクトリの名前を指定するとディレクトリが移動される
res = shutil.move('dir3', 'dir2'# ディレクトリの移動となる
print(res)  # dir2/dir3


ファイルやディレクトリの名前を変更したり、移動したりする方法

 ファイルやディレクトリの名前を変更したり、別のディレクトリに移動したりするには幾つかの方法がある。

 本稿では、このうちshutilモジュールを使用する方法を紹介する。

shutil.move関数

 shutil.move関数の構文を以下に示す。

shutil.move(src, dest)


 srcには名前変更/移動したいファイルやディレクトリを指定する。destには変更後の名前、または移動先のディレクトリを指定する。shutil.move関数は異なるファイルシステム間でのファイル/ディレクトリの移動時には、srcを(再帰的に)コピーした後にsrcを削除するが、ファイルのコピーで使用する関数をcopy_function引数に指定できる(が、本稿では説明を省略する)。なお、shutil.move関数では、srcとdestの両方に、pathlibモジュールで定義されているPathクラスのインスタンスを指定することもできる。

 shutil.move関数は名前変更後/移動後のファイル/ディレクトリの名前を戻り値とする。

 shutil.move関数は基本的に以下のように振る舞う。

移動元 移動先 動作
ファイル 存在しない名前 名前変更
ファイル 存在するファイルの名前 名前変更(上書き)
ファイル 存在するディレクトリの名前 移動
ディレクトリ 存在しない名前 名前変更
ディレクトリ 存在するファイルの名前 FileExistsError
ディレクトリ 存在するディレクトリの名前 移動
shutil.move関数の動作

ファイルの名前変更

 ファイルの名前を変更するにはshutil.move関数に、名前を変更したファイルの名前と変更後の名前を指定する。以下に例を示す。

import shutil
from pathlib import Path

foo = Path('foo.txt')
bar = Path('bar.txt')

foo.touch()  # 準備としてファイルを作成
bar.touch()  # 同上

# ファイルの名前変更
res = shutil.move('foo.txt', 'baz.txt')
print(res)  # baz.txt:戻り値は変更後(移動後)の名前


 この例ではfoo.txtとbar.txtという2つのファイルを作成してから、「shutil.move('foo.txt', 'baz.txt')」としてfoo.txtの名前を「baz.txt」に変更している。その戻り値は変更後のファイルの名前なので、最後のprint関数呼び出しでは「baz.txt」が出力される。

 既存ファイルの名前へ、ファイル名を変更しようとする例を以下に示す。

res = shutil.move('bar.txt', 'baz.txt'# UNIX:OK、Windows:OK
print(res)  # baz.txt


 osモジュールのrename関数やpathlibモジュールのPath.renameインスタンスメソッドを使ってこのようなファイル名の変更を行おうとすると、UNIXでは既存ファイルが上書きされ、WindowsではFileExistsError例外が発生する。しかし、shutil.move関数を使うと、どちらのプラットフォームでも既存のファイルが上書きされる。

ファイルの移動

 destにディレクトリの名前を指定すると、srcに指定したファイルがdestに指定したディレクトリの直下に移動する。以下に例を示す。

dir1 = Path('dir1')
dir1.mkdir()  # dir1ディレクトリを作成

res = shutil.move('baz.txt', 'dir1'# destにディレクトリの名前を指定
print(res)  # dir1/baz.txt:baz.txtファイルがdir1ディレクトリの直下に移動された


 この例ではdir1ディレクトリを作成した後、「shutil.move('baz.txt', 'dir1')」とdestにこのディレクトリの名前を指定している。そのため、上で名前変更したbaz.txtファイルはdir1ディレクトリに移動する。この結果、shutil.move関数は変更後の名前として「dir1/baz.txt」を返す。

 ディレクトリの名前ではなく、ディレクトリを含んだ新しいファイル名をdestに渡してもファイルがそのディレクトリに移動する。

dir2 = Path('dir2')
dir2.mkdir()
res = shutil.move('dir1/baz.txt', 'dir2/qux.txt')
print(res)  # dir2/qux.txt


 この例では、dir2ディレクトリを作成して、上でdir1ディレクトリに移動したbaz.txtファイルをdir2ディレクトリに「qux.txt」という名前で移動している。

 なお、移動先として存在しないディレクトリを含んだパスを渡すと例外が発生する。

shutil.move('dir2/qux.txt', 'dir3/quux.txt'# FileNotFoundError


 これは上で移動したdir2/qux.txtファイルをdir3ディレクトリにquux.txtとして移動しようとしているが、dir3ディレクトリがないのでFileNotFoundError例外が発生する。

ディレクトリの名前変更と移動

 ディレクトリの名前変更はファイルの名前変更と同様、destに存在しないファイル/ディレクトリの名前を指定する。

res = shutil.move('dir1', 'dir3')
print(res)  # dir3


 ここではdir1ディレクトリの名前を「dir3」に変更しようとしている。「dir3」という名前のディレクトリやファイルは存在していないので、これは成功する。

 既に存在しているファイルの名前をdestに指定すると、FileExistsError例外が発生する。

shutil.move('dir3', 'dir2/qux.txt'# FileExistsError


 ここでは、上で名前を変更したdir3ディレクトリの名前を「dir2/qux.txt」に変更しようとしている。「dir2/qux.txt」は上で名前変更したファイルの名前で既に存在しているので、FileExistsError例外が発生する。

 destに既存のディレクトリの名前を指定すると、ディレクトリがそこに移動する。以下に例を示す。

res = shutil.move('dir3', 'dir2'# ディレクトリの移動となる
print(res)  # dir2/dir3


「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。