Python shutil入門 – ファイルコピーと移動の基本をマスター

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)

  • ファイル srcdst にコピーします。
  • 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): srcdst へ移動します。
    • dst が既存のディレクトリの場合: src はそのディレクトリの中に移動されます(名前は src のまま)。
    • dst が存在しないパスの場合: srcdst という名前に変更(リネーム)されます。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")

簡単な注意点

  1. ファイルが存在しない場合
    • コピー元 (src) や移動元 (src) のファイルやディレクトリが存在しない場合、FileNotFoundError が発生します。
  2. 書き込み権限
    • コピー先 (dst) や移動先 (dst) に書き込む権限がない場合、PermissionError が発生することがあります。
  3. 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 のもう少し進んだ機能について解説します。

スポンサーリンク

コメント

タイトルとURLをコピーしました