1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】pathlib × shutil でスマートにファイル操作する

1
Last updated at Posted at 2025-11-17

はじめに

Python でファイルの コピー・移動・削除 を行うとき、

  • パスの扱い → pathlib.Path
  • 実際のコピー・移動系 → shutilPath メソッド

という組み合わせが 一番気持ちいい構成 です。


1. 基本スタイル:Path を使ってから shutil に渡す

まずはお作法から。

from pathlib import Path
import shutil

src = Path("data/input.txt")
dst = Path("backup/input.txt")

dst.parent.mkdir(parents=True, exist_ok=True)  # 必要ならフォルダ作成
shutil.copy2(src, dst)

ポイント:

  • パスは 全部 Path オブジェクト にする
  • shutil には str(src) ではなく そのまま Path を渡してOK(対応済み)
  • dst.parent.mkdir() で、コピー先フォルダも楽に作れる

2. ファイルコピー:shutil.copy / copy2 / copytree

2.1 単純コピー:shutil.copy

from pathlib import Path
import shutil

src = Path("data/report.txt")
dst = Path("backup/report.txt")

dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(src, dst)
  • 中身+パーミッション(モード)をコピー
  • タイムスタンプなどのメタ情報は簡略的

2.2 メタ情報も含めてコピー:copy2

shutil.copy2(src, dst)
  • 更新日時などのメタデータも可能な限りコピーしたいなら copy2 推奨
  • バックアップ用途やログ保全などに使いやすい

2.3 ディレクトリごとコピー:copytree

src_dir = Path("data")
dst_dir = Path("backup/data_copy")

shutil.copytree(src_dir, dst_dir)

注意点:

  • dst_dir既に存在しているとエラー
  • Python 3.8+ なら dirs_exist_ok=True が使える:
shutil.copytree(src_dir, dst_dir, dirs_exist_ok=True)

3. ファイル移動:shutil.move or Path.rename

3.1 一番素直なのは shutil.move

from pathlib import Path
import shutil

src = Path("data/report.txt")
dst = Path("archive/2025/report.txt")

dst.parent.mkdir(parents=True, exist_ok=True)
shutil.move(src, dst)

特徴:

  • ファイルでもディレクトリでも OK
  • 同一ドライブ間なら実質 rename、ドライブ跨ぎならコピー+削除で対応
  • 「とにかく移動したい」時はこれを使うのが無難

3.2 シンプルリネームなら Path.rename

p = Path("data/report.txt")
p.rename("data/report_old.txt")

もしくは Path 同士:

p = Path("data/report.txt")
new_path = p.with_name("report_old.txt")
p.rename(new_path)

注意:

  • 同じファイルシステム内での移動・名前変更 に向いている
  • 別ドライブへの移動などには対応していない(OS依存で失敗することも)

4. 削除:Path.unlink / shutil.rmtree

4.1 ファイル削除:unlink

from pathlib import Path

p = Path("data/tmp.txt")
if p.exists():
    p.unlink()
  • unlink() は「ファイル削除」
  • is_file() でチェックしてから消すのもアリ:
if p.is_file():
    p.unlink()

4.2 空のディレクトリ削除:rmdir

d = Path("data/tmp_folder")
d.rmdir()
  • 中身があるとエラー
  • 「空フォルダだけ整理したい」とき用

4.3 中身ごとディレクトリ削除:shutil.rmtree

import shutil
from pathlib import Path

d = Path("data/tmp_folder")
if d.exists():
    shutil.rmtree(d)
  • サブディレクトリ・ファイル含め 全部まとめて削除
  • 強力なのでパス確認は慎重に(print(d.resolve()) で事前確認おすすめ)

5. ちょっと実践:バックアップ+古いバックアップ削除

要件

  • data/ 以下の内容を backup/YYYYMMDD/ にコピー
  • 7日より前のバックアップフォルダは削除

サンプルコード

from pathlib import Path
import shutil
from datetime import datetime, timedelta

base = Path("backup")
today_str = datetime.now().strftime("%Y%m%d")

src_dir = Path("data")
dst_dir = base / today_str

# 今日のバックアップ作成
dst_dir.mkdir(parents=True, exist_ok=True)
shutil.copytree(src_dir, dst_dir, dirs_exist_ok=True)

# 古いバックアップ削除(7日以前)
limit_date = datetime.now() - timedelta(days=7)

for d in base.iterdir():
    if d.is_dir():
        try:
            dt = datetime.strptime(d.name, "%Y%m%d")
        except ValueError:
            continue  # 変な名前のディレクトリはスキップ

        if dt < limit_date:
            shutil.rmtree(d)
            print(f"削除: {d}")

ポイント:

  • Path.iterdir() でフォルダ一覧取得
  • フォルダ名を日付としてパース
  • shutil.copytree + shutil.rmtree でコピー&削除

6. どう使い分ければいい?

ざっくり表にするとこんな感じ:

操作 推奨API 補足
ファイルコピー shutil.copy2(src, dst) メタ情報も保存したいなら copy2
フォルダコピー shutil.copytree(src_dir, dst_dir) 既存フォルダに上書きなら dirs_exist_ok=True
ファイル移動 shutil.move(src, dst) ドライブ跨ぎも含めて安心
ちょっとしたリネーム Path.rename(new_path) 同一ファイルシステム前提
単一ファイル削除 Path.unlink() ファイル専用
空フォルダ削除 Path.rmdir() 空でないとエラー
フォルダまるごと削除 shutil.rmtree(path) 破壊力あるので要注意

まとめ

  • パスの扱いは pathlib.Path に寄せる(/ 演算子・親ディレクトリ・名前操作が楽)
  • コピー・移動・削除など「中身をいじる系」は shutil + 一部 Path メソッドを使う
  • copy2 / copytree / move / rmtree あたりを覚えておくと、大抵のバッチ処理やツールが書ける

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?