Pythonでプログラミングをしていると、「このファイルを別の場所にコピーしたい」「ファイル名を変更したい」「フォルダごと移動させたい」といったファイル操作が必要になる場面は非常に多いですよね。
Pythonには、こうした基本的なファイル・ディレクトリ操作を簡単に行える標準ライブラリ shutil
があります。
この記事は、shutil
モジュールを初めて使う方や、ファイルのコピー・移動方法を知りたい初心者向けの内容です。
- 「
shutil
って何?」という基本 - ファイルのコピー (
copy
,copy2
,copyfile
) - 移動・リネーム (
move
) の具体的な使い方
まで、サンプルコードを交えて分かりやすく解説します。
この記事を読めば、Pythonを使った基本的なファイル操作の第一歩を踏み出し、shutil
の便利さを実感できるはずです。
shutilモジュールとは? – ファイル操作をもっと簡単に
shutil
は “shell utilities” の略で、コマンドライン(シェル)で行うようなファイル操作をPythonプログラムから高水準(=より少ないコードで、より直感的)に実行できるようにしたモジュールです。
Pythonには os
モジュールというファイルシステム操作の基本機能を提供するものもありますが、os
モジュールがファイル一つ、ディレクトリ一つといった低水準な操作が中心なのに対し、shutil
はファイルコピーや移動、ディレクトリツリーの操作などをより便利に行える関数を提供しています。
日常的なファイル操作の多くは shutil
を使う方がコードが簡潔になります。
ファイルをコピーする – copy(), copy2(), copyfile() の違いと使い方
ファイルのコピーは shutil
の最も基本的な機能の一つです。目的に合わせて3つの関数を使い分けます。
shutil.copy(src, dst)
- ファイル
src
をdst
にコピーします。 dst
がディレクトリなら、その中にsrc
と同名でコピーされます。- ファイル名は
dst
で指定できます。 - パーミッション(実行権限など)はコピーされません。
- 最終アクセス時刻や最終更新時刻などの一部メタデータはコピーを試みます。
shutil.copy2(src, dst)
copy()
と似ていますが、可能な限り全てのメタデータ(パーミッション、最終アクセス時刻、最終更新時刻など)も一緒にコピーします。- ファイルの情報を完全に保持したままコピーしたい場合に最適です。
shutil.copyfile(src, dst)
- ファイルの内容のみを
src
からdst
にコピーします。 - メタデータやパーミッションは一切コピーしません。
dst
は必ずファイル名を指定する必要があります(ディレクトリは不可)。- コピー先にファイルが存在すれば上書きします。
使い分けのポイント:
関数 | 内容コピー | パーミッションコピー | メタデータコピー | dst にディレクトリ指定 |
おすすめの場面 |
---|---|---|---|---|---|
copy() |
Yes | No | 一部試行 | OK | とりあえずファイルをコピーしたい時 |
copy2() |
Yes | Yes | Yes | OK | 元の情報を完全に保持したい時 |
copyfile() |
Yes | No | No | NG (エラー) | ファイルの中身だけ欲しい時 |
コード例:
Python
import shutil
import os
# 事前準備
os.makedirs("copy_dest", exist_ok=True)
with open("source.txt", "w") as f:
f.write("コピー元ファイルの内容です。")
print("--- shutil.copy() の実行 ---")
try:
# copy_dest フォルダに source.txt をコピー
shutil.copy("source.txt", "copy_dest")
print("'copy_dest' フォルダにコピーしました。")
# 別の名前でコピー
shutil.copy("source.txt", "copied_by_copy.txt")
print("'copied_by_copy.txt' としてコピーしました。")
except Exception as e:
print(f"copy エラー: {e}")
print("\n--- shutil.copy2() の実行 ---")
try:
# メタデータごとコピー
shutil.copy2("source.txt", "copied_by_copy2.txt")
print("'copied_by_copy2.txt' としてメタデータごとコピーしました。")
except Exception as e:
print(f"copy2 エラー: {e}")
print("\n--- shutil.copyfile() の実行 ---")
try:
# 内容のみコピー (ファイル名を指定)
shutil.copyfile("source.txt", "copied_by_copyfile.txt")
print("'copied_by_copyfile.txt' として内容のみコピーしました。")
# ディレクトリを指定するとエラーになる例 (コメントアウト)
# shutil.copyfile("source.txt", "copy_dest")
except Exception as e:
print(f"copyfile エラー: {e}")
# 後片付け (必要に応じてコメント解除)
# os.remove("source.txt")
# os.remove("copied_by_copy.txt")
# os.remove("copied_by_copy2.txt")
# os.remove("copied_by_copyfile.txt")
# shutil.rmtree("copy_dest") # rmtreeは記事2で解説
ファイルやディレクトリを移動・リネームする – shutil.move()
ファイルの場所を移動したり、ファイルやディレクトリの名前を変更したりするには shutil.move()
を使います。
shutil.move(src, dst)
:src
をdst
へ移動します。dst
が既存のディレクトリの場合:src
はそのディレクトリの中に移動されます(名前はsrc
のまま)。dst
が存在しないパスの場合:src
はdst
という名前に変更(リネーム)されます。src
がファイルならファイルのリネーム、src
がディレクトリならディレクトリのリネームになります。- 異なるディスク間での移動も可能:
os.rename()
は同じディスク(ファイルシステム)内での移動しかできませんが、shutil.move()
は内部でコピー&削除を行うことで、異なるディスク間の移動も実現します。
コード例:
Python
import shutil
import os
# 事前準備
os.makedirs("move_origin/subdir", exist_ok=True)
with open("move_origin/file_to_move.txt", "w") as f:
f.write("移動されるファイル")
os.makedirs("move_destination", exist_ok=True) # 移動先ディレクトリ
print("--- ファイルをディレクトリへ移動 ---")
try:
# 'file_to_move.txt' を 'move_destination' フォルダへ移動
shutil.move("move_origin/file_to_move.txt", "move_destination")
print("'move_origin/file_to_move.txt' を 'move_destination' へ移動しました。")
# 移動元にファイルがないことを確認
print(f"移動元のファイル存在確認: {os.path.exists('move_origin/file_to_move.txt')}") # False になるはず
# 移動先にファイルがあることを確認
print(f"移動先のファイル存在確認: {os.path.exists('move_destination/file_to_move.txt')}") # True になるはず
except Exception as e:
print(f"ファイル移動エラー: {e}")
print("\n--- ディレクトリをリネーム(移動) ---")
try:
# 'move_origin' ディレクトリを 'renamed_origin' という名前に変更
shutil.move("move_origin", "renamed_origin")
print("'move_origin' ディレクトリを 'renamed_origin' にリネームしました。")
print(f"元のディレクトリ存在確認: {os.path.exists('move_origin')}") # False になるはず
print(f"リネーム後のディレクトリ存在確認: {os.path.exists('renamed_origin')}") # True になるはず
except Exception as e:
print(f"ディレクトリリネームエラー: {e}")
# 後片付け (必要に応じてコメント解除)
# shutil.rmtree("move_destination")
# shutil.rmtree("renamed_origin")
簡単な注意点
- ファイルが存在しない場合
- コピー元 (
src
) や移動元 (src
) のファイルやディレクトリが存在しない場合、FileNotFoundError
が発生します。
- コピー元 (
- 書き込み権限
- コピー先 (
dst
) や移動先 (dst
) に書き込む権限がない場合、PermissionError
が発生することがあります。
- コピー先 (
move()
の上書き- 移動先に同名のファイルやディレクトリが既に存在する場合、
move()
はそれを上書きしてしまう可能性があります(OSや状況によります)。上書きしたくない場合は、事前にos.path.exists()
などで存在確認を行うと安全です。
- 移動先に同名のファイルやディレクトリが既に存在する場合、
これらのエラーへの対処法(エラーハンドリング)については、シリーズの【記事3/3】で詳しく解説します。
まとめ
今回は Python の shutil
モジュールを使った基本的なファイルのコピーと移動・リネーム操作について解説しました。
shutil
はファイル操作を簡単にする高水準モジュール。- ファイルのコピー
- とりあえずコピーなら
shutil.copy()
- メタデータも完全にコピーするなら
shutil.copy2()
- 内容だけコピーなら
shutil.copyfile()
- とりあえずコピーなら
- ファイルやディレクトリの移動・リネームには
shutil.move()
を使う。- ディレクトリへの移動も、名前の変更も
move()
で可能。 - 異なるディスク間でも移動できるのが便利。
- ディレクトリへの移動も、名前の変更も
これらの基本的な関数を覚えるだけで、Pythonでのファイル操作がぐっと楽になります。ぜひ実際に試してみてください。
次の記事【記事2/3】では、ディレクトリ全体のコピー (copytree
) や削除 (rmtree
)、ディスク情報の取得など、shutil
のもう少し進んだ機能について解説します。
コメント