【完全ガイド】Pythonでファイル整理を自動化

ソニック

事務職のフォルダ地獄から抜け出す方法

「ダウンロードフォルダがゴチャゴチャ」「請求書ファイルが何百も散らばっている」「PDFがどこに保存したか分からない」

そんな経験、事務職なら毎日のようにあるはずです。

私自身、学校事務員時代に「Excelファイルが何百枚もあるフォルダ」を整理する作業に毎週1時間以上かけていました。日付別、種類別、担当者別…手作業でフォルダ分けするだけで本当に消耗していました。

そんな業務を変えたのが、Pythonでのファイル整理自動化でした。500個のファイルが、たった3秒で綺麗に分類されます。

この記事では、Pythonでファイル整理を自動化する方法を、コピペで使えるコード付きで完全解説します。

目次

こんな方におすすめ

  • ダウンロードフォルダや業務フォルダがゴチャゴチャな事務職の方
  • ファイルの命名規則・フォルダ分けに毎週時間を取られているバックオフィスの方
  • Python業務自動化の「次の一歩」を学びたい方

第1章|なぜ「ファイル整理の自動化」が業務を変えるのか

事務職のフォルダ地獄リアル

事務職のPC、こんな状態ではないですか?

  • デスクトップに50個以上のファイルが散乱
  • 「請求書」フォルダに2年分のファイルが混在
  • 「最終_最終_本当に最終.xlsx」が何十個も並ぶ
  • 似た名前のファイルがあり、どれが最新か分からない
  • 古いファイルを削除する勇気がなく、容量を圧迫

ファイル整理の自動化で実現できること

  • 拡張子別の自動振り分け(.xlsx、.pdf、.png など)
  • 日付別の自動アーカイブ(202601、202602…)
  • 命名規則の一括統一(請求書_YYYYMM_顧客名.pdf)
  • 古いファイルの自動圧縮・移動
  • 重複ファイルの自動検出・削除

Before/After|ファイル整理自動化の威力

業務Before(手作業)After(Python自動化)
500ファイルの分類週1時間3秒
ファイル名の統一1個ずつリネーム一括処理
古いファイルの移動放置・容量圧迫自動アーカイブ
月間整理時間4時間以上数秒(自動実行)

第2章|環境準備(uv環境前提)

この記事は、uv環境でPythonを使う前提で進めます。まだuvをインストールしていない方は、別記事「【完全版】uv入門」をご覧ください。

使うライブラリ(標準ライブラリのみ)

ファイル整理は、**Python標準ライブラリだけで完結**するのが嬉しい点。追加インストールは不要です。

ライブラリ役割
osファイル・フォルダの基本操作
shutilファイルの移動・コピー・削除
pathlibモダンなパス操作(推奨)
datetime日付情報の取得
globパターンマッチでファイル取得

全て標準ライブラリのため、`uv add`不要。Pythonをインストールした時点で使えます。

第3章|基本|Pythonでファイル一覧を取得する

最小のファイル一覧取得

# pathlibを使う方法(推奨)
from pathlib import Path

# 対象フォルダを指定
folder = Path("C:/Users/YourName/Downloads")

# フォルダ内の全ファイルを取得
for file in folder.iterdir():
    if file.is_file():  # ファイルのみ(フォルダは除く)
        print(file.name)

特定の拡張子のファイルだけ取得

from pathlib import Path

folder = Path("C:/Users/YourName/Downloads")

# .xlsx ファイルだけ取得
for file in folder.glob("*.xlsx"):
    print(file.name)

# .pdf ファイルだけ取得
for file in folder.glob("*.pdf"):
    print(file.name)

# 複数の拡張子(.xlsx と .csv)
for file in folder.iterdir():
    if file.suffix in [".xlsx", ".csv"]:
        print(file.name)

サブフォルダも含めて再帰的に取得

from pathlib import Path

folder = Path("C:/Users/YourName/Documents")

# サブフォルダも含めて全ファイル
for file in folder.rglob("*"):
    if file.is_file():
        print(file)

# サブフォルダ含めて.pdfだけ
for file in folder.rglob("*.pdf"):
    print(file)

※ rglob(recursive glob)を使うと、サブフォルダも全て探索できる。階層が深いフォルダ整理に便利。

ファイル情報の取得

from pathlib import Path
from datetime import datetime

file = Path("C:/Users/YourName/Downloads/sample.xlsx")

if file.exists():
    print(f"ファイル名:{file.name}")
    print(f"拡張子:{file.suffix}")
    print(f"サイズ:{file.stat().st_size} バイト")
    print(f"最終更新日:{datetime.fromtimestamp(file.stat().st_mtime)}")
    print(f"親フォルダ:{file.parent}")

第4章|ファイルの分類・移動を自動化

拡張子別にフォルダを分けて移動

「ダウンロードフォルダ」をPythonに見せると、自動でファイルを種類別に振り分けてくれます。

from pathlib import Path
import shutil

# 整理したいフォルダ
source = Path("C:/Users/YourName/Downloads")

# 拡張子と振り分け先フォルダの対応
category = {
    ".xlsx": "Excelファイル",
    ".xls":  "Excelファイル",
    ".csv":  "CSVファイル",
    ".pdf":  "PDFファイル",
    ".png":  "画像ファイル",
    ".jpg":  "画像ファイル",
    ".docx": "Wordファイル",
    ".pptx": "PowerPointファイル",
}

# 各ファイルを分類
for file in source.iterdir():
    if not file.is_file():
        continue
    
    # 拡張子から振り分け先を判定
    folder_name = category.get(file.suffix.lower(), "その他")
    target_folder = source / folder_name
    
    # 振り分け先フォルダを作成(既存ならスキップ)
    target_folder.mkdir(exist_ok=True)
    
    # ファイルを移動
    shutil.move(str(file), str(target_folder / file.name))
    print(f"移動:{file.name} → {folder_name}/")

print("\n整理完了!")

日付別にアーカイブ

「2026年6月分」「2026年5月分」のように、**年月別フォルダ**に自動で振り分けます。

from pathlib import Path
import shutil
from datetime import datetime

source = Path("C:/Users/YourName/Downloads")

for file in source.iterdir():
    if not file.is_file():
        continue
    
    # ファイルの最終更新日を取得
    mtime = datetime.fromtimestamp(file.stat().st_mtime)
    
    # 「YYYYMM」形式のフォルダ名を作成
    folder_name = mtime.strftime("%Y%m")
    target_folder = source / folder_name
    
    # フォルダ作成&移動
    target_folder.mkdir(exist_ok=True)
    shutil.move(str(file), str(target_folder / file.name))
    print(f"移動:{file.name} → {folder_name}/")

print("\n月別アーカイブ完了!")

第5章|ファイル名の一括変更

命名規則の統一

「半角全角混在」「日付フォーマットがバラバラ」「スペースが入っている」――こうした命名問題を一括で解決。

先頭・末尾に文字を追加

from pathlib import Path

folder = Path("C:/Users/YourName/Documents/請求書")

# 全ファイル名の先頭に「請求書_」を追加
for file in folder.glob("*.pdf"):
    new_name = "請求書_" + file.name
    file.rename(folder / new_name)
    print(f"リネーム:{file.name} → {new_name}")

print("\n命名統一完了!")

特定の文字を置換

from pathlib import Path

folder = Path("C:/Users/YourName/Documents")

# ファイル名内の半角スペースをアンダースコアに置換
for file in folder.iterdir():
    if " " in file.name:
        new_name = file.name.replace(" ", "_")
        file.rename(folder / new_name)
        print(f"置換:{file.name} → {new_name}")

連番を振る(リネーム)

from pathlib import Path

folder = Path("C:/Users/YourName/Pictures/旅行写真")

# 「旅行_001.jpg」「旅行_002.jpg」のように連番を振る
files = sorted(folder.glob("*.jpg"))

for index, file in enumerate(files, start=1):
    new_name = f"旅行_{index:03d}.jpg"  # 003桁ゼロ埋め
    file.rename(folder / new_name)
    print(f"連番化:{file.name} → {new_name}")

日付を含めたリネーム

from pathlib import Path
from datetime import datetime

folder = Path("C:/Users/YourName/Documents/レポート")

# 全ファイルの先頭に「YYYYMMDD_」を付ける(最終更新日ベース)
for file in folder.glob("*.docx"):
    mtime = datetime.fromtimestamp(file.stat().st_mtime)
    date_str = mtime.strftime("%Y%m%d")
    new_name = f"{date_str}_{file.name}"
    file.rename(folder / new_name)
    print(f"日付付与:{file.name} → {new_name}")

第6章|古いファイルの自動アーカイブ

「30日以上前のファイル」を別フォルダに移動

「最新のファイルだけ手元に置いて、古いものはアーカイブに移したい」――そんなニーズに対応するスクリプト。

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

# 対象フォルダとアーカイブ先
source = Path("C:/Users/YourName/Documents/作業中")
archive = Path("C:/Users/YourName/Documents/アーカイブ")

# アーカイブフォルダを作成
archive.mkdir(exist_ok=True)

# 30日前の日付を計算
cutoff = datetime.now() - timedelta(days=30)

moved_count = 0
for file in source.iterdir():
    if not file.is_file():
        continue
    
    # 最終更新日を取得
    mtime = datetime.fromtimestamp(file.stat().st_mtime)
    
    # 30日より古いファイルを移動
    if mtime < cutoff:
        shutil.move(str(file), str(archive / file.name))
        print(f"アーカイブ:{file.name}({mtime.strftime('%Y-%m-%d')})")
        moved_count += 1

print(f"\n{moved_count}件のファイルをアーカイブしました")

一定容量を超えるファイルを抽出

「容量を食っている大きなファイルを発見したい」場合のスクリプト。

from pathlib import Path

folder = Path("C:/Users/YourName/Documents")
min_size_mb = 10  # 10MB以上を抽出

print(f"=== {min_size_mb}MB以上のファイル ===")
for file in folder.rglob("*"):
    if not file.is_file():
        continue
    
    size_mb = file.stat().st_size / (1024 * 1024)
    if size_mb >= min_size_mb:
        print(f"{size_mb:>6.1f} MB | {file}")

第7章|実務スクリプト|月次フォルダ整理バッチ

シナリオ

毎月1日に実行するだけで、ダウンロードフォルダを自動整理する完成スクリプト。

完成スクリプト

"""
月次フォルダ整理バッチ
- ダウンロードフォルダを自動整理
- 拡張子別に分類
- 古いファイルをアーカイブ
- 実行ログをファイル出力
"""
from pathlib import Path
import shutil
from datetime import datetime, timedelta

# === 設定 ===
SOURCE = Path("C:/Users/YourName/Downloads")
ARCHIVE = SOURCE / "アーカイブ"
LOG_FILE = SOURCE / f"整理ログ_{datetime.now().strftime('%Y%m%d')}.txt"
ARCHIVE_DAYS = 30  # 何日以上前のファイルをアーカイブするか

# 拡張子の分類
CATEGORIES = {
    ".xlsx": "Excelファイル", ".xls": "Excelファイル",
    ".csv":  "CSVファイル",
    ".pdf":  "PDFファイル",
    ".png":  "画像ファイル", ".jpg": "画像ファイル", ".jpeg": "画像ファイル",
    ".docx": "Wordファイル", ".doc": "Wordファイル",
    ".pptx": "PowerPointファイル", ".ppt": "PowerPointファイル",
    ".txt":  "テキストファイル",
    ".zip":  "圧縮ファイル", ".rar": "圧縮ファイル",
}

def main():
    print(f"=== 月次フォルダ整理開始 ===")
    print(f"対象フォルダ:{SOURCE}")
    
    # アーカイブフォルダを作成
    ARCHIVE.mkdir(exist_ok=True)
    cutoff = datetime.now() - timedelta(days=ARCHIVE_DAYS)
    
    classify_count = 0
    archive_count = 0
    
    # ログをファイル出力
    with open(LOG_FILE, "w", encoding="utf-8") as log:
        log.write(f"実行日時:{datetime.now()}\n")
        log.write(f"対象:{SOURCE}\n")
        log.write("=" * 50 + "\n\n")
        
        # === ステップ1:古いファイルのアーカイブ ===
        log.write("【ステップ1:アーカイブ】\n")
        for file in SOURCE.iterdir():
            if not file.is_file():
                continue
            if file.name == LOG_FILE.name:  # ログ自身は除外
                continue
            
            mtime = datetime.fromtimestamp(file.stat().st_mtime)
            if mtime < cutoff:
                try:
                    shutil.move(str(file), str(ARCHIVE / file.name))
                    log.write(f"  アーカイブ:{file.name}\n")
                    archive_count += 1
                except Exception as e:
                    log.write(f"  エラー:{file.name}({e})\n")
        
        # === ステップ2:拡張子別に分類 ===
        log.write("\n【ステップ2:分類】\n")
        for file in SOURCE.iterdir():
            if not file.is_file():
                continue
            if file.name == LOG_FILE.name:
                continue
            
            folder_name = CATEGORIES.get(file.suffix.lower(), "その他")
            target_folder = SOURCE / folder_name
            target_folder.mkdir(exist_ok=True)
            
            try:
                shutil.move(str(file), str(target_folder / file.name))
                log.write(f"  {file.name} → {folder_name}/\n")
                classify_count += 1
            except Exception as e:
                log.write(f"  エラー:{file.name}({e})\n")
        
        # === サマリ ===
        log.write("\n" + "=" * 50 + "\n")
        log.write(f"アーカイブ:{archive_count}件\n")
        log.write(f"分類:{classify_count}件\n")
    
    print(f"\n=== 完了 ===")
    print(f"アーカイブ:{archive_count}件、分類:{classify_count}件")
    print(f"ログ:{LOG_FILE}")

if __name__ == "__main__":
    main()

このスクリプトでできること

  • 30日以上前のファイルを「アーカイブ」フォルダへ自動移動
  • 残ったファイルを拡張子別に分類フォルダへ移動
  • 実行ログをテキストファイルに保存
  • エラーが起きても他の処理を続行

毎月1日に自動実行したい場合は、Windowsの「タスクスケジューラ」やMacの「cron」で設定可能。完全無人化が実現します。

第8章|つまずき対処&まとめ

よくあるトラブル

トラブル1:パスが見つからない・PermissionError

原因:

パスの区切り文字が間違っている、または管理者権限が必要。

対処:

# Windowsでは「/」または「\\」を使う(バックスラッシュは2重に)
folder = Path("C:/Users/YourName/Downloads")  # OK
folder = Path("C:\\Users\\YourName\\Downloads")  # OK
folder = Path("C:\Users\YourName\Downloads")  # NG(\Uがエスケープ扱い)

トラブル2:移動先にすでに同名ファイルがある

対処:

# 既存ファイルがあれば連番を付ける処理
from pathlib import Path
import shutil

def safe_move(src, dst_folder):
    dst = dst_folder / src.name
    counter = 1
    while dst.exists():
        # 「sample.xlsx」→「sample_1.xlsx」→「sample_2.xlsx」
        dst = dst_folder / f"{src.stem}_{counter}{src.suffix}"
        counter += 1
    shutil.move(str(src), str(dst))
    return dst

トラブル3:実行する前に内容を確認したい

対処:

最初は「実際に移動せず、何が起きるかだけ表示する」ドライランで確認しましょう。

# ドライラン(実際には移動しない)
DRY_RUN = True  # Falseにすれば実際に移動

for file in source.iterdir():
    folder_name = category.get(file.suffix.lower(), "その他")
    print(f"[ドライラン] {file.name} → {folder_name}/")
    
    if not DRY_RUN:
        # ここで実際に移動
        target = source / folder_name
        target.mkdir(exist_ok=True)
        shutil.move(str(file), str(target / file.name))

トラブル4:日本語ファイル名が文字化け

対処:

Windowsで日本語ファイル名を扱う場合、ターミナルの文字コード設定によって表示が崩れることがあります。pathlibを使えば、ファイル操作自体は問題なく動きます。

この記事のまとめ

  1. Pythonでファイル整理を自動化すれば、週1時間の業務が数秒に
  2. pathlib + shutilだけで、ほとんどの整理業務が可能
  3. 拡張子別・日付別・命名規則別の自動分類が簡単
  4. 古いファイルの自動アーカイブで容量管理も自動化
  5. 月次バッチ化でフォルダ整理を完全無人化できる

FAQ

Q1. 間違ってファイルを消したら戻せますか?

shutil.move() はWindowsならゴミ箱を経由しません。重要なファイルを扱う場合は、最初にドライラン(DRY_RUN=True)で確認するか、send2trash ライブラリを使ってゴミ箱に送る形にしましょう。

Q2. 隠しファイル(.から始まる)も対象になりますか?

iterdir() は隠しファイルも含めて取得します。隠しファイルを除外したい場合は `if not file.name.startswith(‘.’)` の条件を追加してください。

Q3. ネットワーク上の共有フォルダにも使えますか?

はい、ネットワークパス(\\\\server\\share\\folder)も指定可能。ただしアクセス権が必要です。会社の共有フォルダで使う場合は、必ず管理者の許可を得てから実行してください。

Q4. 定期実行したい

Windowsの「タスクスケジューラ」かMacの「cron」で、毎月1日朝などに自動実行できます。完全無人化で、フォルダがいつでも綺麗に保たれます。

Q5. もっと高度なファイル管理がしたい

次のステップとして、メタデータ抽出(exifread、PyPDF2)、ファイル内容での分類(テキスト解析)、クラウド連携(Google Drive API)などへ進めます。

次にやるべき3つの行動

  • **今すぐ**:自分のダウンロードフォルダを開いて、ファイル数を数えてみる
  • **今日中**:第4章のコードで、最初の1つを自動分類してみる(ドライラン推奨)
  • **今週中**:第7章の月次バッチを実装し、タスクスケジューラで自動化

週1時間のフォルダ整理が、数秒の自動実行に。空いた時間で、本来の業務に集中できます。

ファイル整理自動化で、業務が変わる

ダウンロードフォルダ・請求書フォルダ・写真フォルダ――定型のファイル整理は、Pythonで全て自動化できます。

「毎週の整理作業」を「自動実行」に変えれば、PCが綺麗な状態で常に保たれる。業務効率化の本質は、こうした地味な作業の自動化にあります。

最新の解説記事は、新着記事から順次公開しています。X(旧Twitter)でも更新情報を発信していますので、ぜひフォローしてください。

この記事を書いた人

ソニック|バックオフィス出身の業務効率化ブロガー。学校事務員時代に毎週1時間かけていたファイル整理を、Pythonで完全自動化した実体験あり。現在のデータサイエンス業務でも、大量データファイルの管理にPythonを毎日活用中。リアルな実体験をもとにしたノウハウを発信中。

→ 詳しいプロフィールはこちら→ はじめての方へ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次