Pythonでファイル・ディレクトリを移動する方法(shutil.move完全ガイド)
Pythonでファイルやディレクトリを移動する際に使用するshutil.move()の使い方を、実践的なサンプルコードと共に詳しく解説します。
目次
基本的なファイル移動:shutil.move()
ファイルの移動
import shutil
# ファイルを別のディレクトリに移動
shutil.move('sample.txt', 'documents/sample.txt')
ファイル名変更を伴う移動
import shutil
# 移動と同時にファイル名も変更
shutil.move('old_name.txt', 'new_folder/new_name.txt')
ディレクトリの移動
ディレクトリ全体の移動
import shutil
# ディレクトリを丸ごと移動
shutil.move('source_folder', 'destination/source_folder')
存在しない移動先ディレクトリの作成
import os
import shutil
def safe_move(src, dst):
# 移動先ディレクトリが存在しない場合は作成
dst_dir = os.path.dirname(dst)
if dst_dir and not os.path.exists(dst_dir):
os.makedirs(dst_dir)
shutil.move(src, dst)
return f"'{src}' を '{dst}' に移動しました"
# 使用例
print(safe_move('file.txt', 'deep/nested/folder/file.txt'))
エラーハンドリングを含む安全な移動
基本的なエラーハンドリング
import shutil
import os
def move_with_error_handling(src, dst):
try:
if not os.path.exists(src):
return f"エラー: '{src}' が存在しません"
shutil.move(src, dst)
return f"移動完了: '{src}' → '{dst}'"
except PermissionError:
return "エラー: 権限がありません"
except shutil.Error as e:
return f"移動エラー: {e}"
except Exception as e:
return f"予期しないエラー: {e}"
# 使用例
print(move_with_error_handling('test.txt', 'backup/test.txt'))
同名ファイル対応の移動
import os
import shutil
def move_with_rename(src, dst):
if os.path.exists(dst):
base, ext = os.path.splitext(dst)
counter = 1
while os.path.exists(f"{base}_{counter}{ext}"):
counter += 1
dst = f"{base}_{counter}{ext}"
shutil.move(src, dst)
return dst
# 使用例
new_path = move_with_rename('file.txt', 'backup/file.txt')
print(f"移動先: {new_path}")
パターン指定での一括移動
glob を使った複数ファイル移動
import glob
import shutil
import os
def move_files_by_pattern(pattern, destination):
# 移動先ディレクトリを作成
os.makedirs(destination, exist_ok=True)
files = glob.glob(pattern)
moved_files = []
for file in files:
filename = os.path.basename(file)
dst = os.path.join(destination, filename)
shutil.move(file, dst)
moved_files.append(filename)
return moved_files
# 使用例:すべての.txtファイルをbackupフォルダに移動
moved = move_files_by_pattern('*.txt', 'backup')
print(f"移動したファイル: {moved}")
条件指定での移動
import os
import shutil
import time
def move_old_files(source_dir, dest_dir, days_old=30):
os.makedirs(dest_dir, exist_ok=True)
cutoff_time = time.time() - (days_old * 24 * 60 * 60)
moved_count = 0
for filename in os.listdir(source_dir):
filepath = os.path.join(source_dir, filename)
if os.path.isfile(filepath):
if os.path.getmtime(filepath) < cutoff_time:
dst = os.path.join(dest_dir, filename)
shutil.move(filepath, dst)
moved_count += 1
return moved_count
# 使用例:30日以上古いファイルを移動
count = move_old_files('current', 'archive', 30)
print(f"{count}個のファイルを移動しました")
高度な移動操作
進捗表示付き移動
import shutil
import os
def move_with_progress(src, dst):
def progress_callback(copied, total):
percent = (copied / total) * 100
print(f"\r移動進捗: {percent:.1f}%", end='')
# ファイルサイズが大きい場合の進捗表示
if os.path.isfile(src):
file_size = os.path.getsize(src)
if file_size > 1024 * 1024: # 1MB以上
print(f"大きなファイルを移動中...")
shutil.move(src, dst)
print(f"\n移動完了: {dst}")
# 使用例
move_with_progress('large_file.zip', 'backup/large_file.zip')
バックアップ付き移動
import shutil
import os
from datetime import datetime
def move_with_backup(src, dst):
# 移動先に同名ファイルがある場合はバックアップ
if os.path.exists(dst):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_name = f"{dst}.backup_{timestamp}"
shutil.move(dst, backup_name)
print(f"既存ファイルをバックアップ: {backup_name}")
shutil.move(src, dst)
print(f"移動完了: {src} → {dst}")
# 使用例
move_with_backup('new_config.txt', 'config/config.txt')
ファイル移動の検証
移動後の整合性チェック
import shutil
import os
import hashlib
def move_and_verify(src, dst):
# 移動前のハッシュ値を計算
with open(src, 'rb') as f:
original_hash = hashlib.md5(f.read()).hexdigest()
# ファイル移動
shutil.move(src, dst)
# 移動後のハッシュ値を確認
with open(dst, 'rb') as f:
moved_hash = hashlib.md5(f.read()).hexdigest()
if original_hash == moved_hash:
return f"移動成功: ハッシュ値一致 ({dst})"
else:
return f"移動エラー: ハッシュ値不一致"
# 使用例(テキストファイル以外で使用)
# result = move_and_verify('data.bin', 'backup/data.bin')
# print(result)
ディスク容量チェック付き移動
import shutil
import os
def move_with_space_check(src, dst):
# ファイルサイズを取得
if os.path.isfile(src):
file_size = os.path.getsize(src)
else:
# ディレクトリの場合は合計サイズを計算
file_size = sum(
os.path.getsize(os.path.join(dirpath, filename))
for dirpath, dirnames, filenames in os.walk(src)
for filename in filenames
)
# 移動先の空き容量を確認
dst_dir = os.path.dirname(dst) or '.'
free_space = shutil.disk_usage(dst_dir).free
if file_size > free_space:
return f"エラー: 容量不足 (必要: {file_size}, 空き: {free_space})"
shutil.move(src, dst)
return f"移動完了: {dst}"
# 使用例
print(move_with_space_check('large_folder', 'external_drive/large_folder'))
まとめ
shutil.move()は以下の特徴を持つ強力な関数です:
- ファイルとディレクトリの両方に対応
- 移動先が同じファイルシステム内なら高速な名前変更
- 異なるファイルシステム間ではコピー後削除を実行
- 移動先ディレクトリが存在しない場合は自動作成
エラーハンドリング、進捗表示、バックアップ機能を追加することで、より堅牢で使いやすい移動機能を実装できます。
■らくらくPython塾 – 読むだけでマスター
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座
