再帰フォルダ検索は「階層構造を丸ごと探索する」ための最重要テクニック
業務自動化では、フォルダが1階層とは限りません。
実際には、次のような階層構造が普通に存在します。
project/
├── data/
│ ├── 2024/
│ │ ├── jan/
│ │ └── feb/
│ └── 2025/
└── logs/
このような構造の中から「特定の拡張子だけ探したい」「最新ファイルを探したい」「特定の文字列を含むファイルだけ抽出したい」などの処理を行うには、再帰的なフォルダ検索が必須です。
Pythonでは主に os.walk() と pathlib.Path.rglob() を使います。
どちらも強力ですが、考え方はシンプルです。
os.walk を使った再帰検索の基本
os.walk の仕組みを理解する
os.walk() は、指定したフォルダ以下のすべての階層を「歩きながら」探索する関数です。
import os
root = "project"
for current, dirs, files in os.walk(root):
print("今いるフォルダ:", current)
print("サブフォルダ:", dirs)
print("ファイル:", files)
Pythonここで重要なのは、os.walk() が 階層を自動で潜ってくれる という点です。
自分で再帰処理を書く必要はありません。
再帰的にファイルを検索する基本テンプレート
すべてのファイルを列挙する
import os
root = "project"
for current, dirs, files in os.walk(root):
for name in files:
path = os.path.join(current, name)
print(path)
Pythonこのテンプレートは「階層構造を丸ごと探索する」ための基本形です。
条件付き検索:拡張子・部分一致・更新日時など
拡張子で絞り込む
import os
root = "project"
for current, dirs, files in os.walk(root):
for name in files:
if name.lower().endswith(".csv"):
print("CSV:", os.path.join(current, name))
Python名前の部分一致で絞り込む
import os
root = "project"
for current, dirs, files in os.walk(root):
for name in files:
if "report" in name.lower():
print("report を含む:", os.path.join(current, name))
Python更新日時で絞り込む
import os
from datetime import datetime, timedelta
root = "project"
limit = datetime.now() - timedelta(days=7)
for current, dirs, files in os.walk(root):
for name in files:
path = os.path.join(current, name)
ts = os.path.getmtime(path)
dt = datetime.fromtimestamp(ts)
if dt >= limit:
print("最近更新:", dt, path)
Python更新日時を使うと「最近更新されたファイルだけ処理する」などの業務に応用できます。
例題①:サブフォルダを含めて CSV ファイルだけを一覧化する
シナリオ
プロジェクト全体から .csv ファイルだけを探したい。
コード例
import os
root = "project"
csv_files = []
for current, dirs, files in os.walk(root):
for name in files:
if name.lower().endswith(".csv"):
csv_files.append(os.path.join(current, name))
for f in csv_files:
print(f)
Python深掘りポイント
- 結果をリストに保存して後でまとめて処理できる
- 大規模フォルダでも高速に動作する
例題②:最新のファイルを階層全体から1つだけ探す
シナリオ
階層全体の中で「最も新しいファイル」を見つけたい。
コード例
import os
from datetime import datetime
root = "project"
latest_path = None
latest_ts = None
for current, dirs, files in os.walk(root):
for name in files:
path = os.path.join(current, name)
ts = os.path.getmtime(path)
if latest_ts is None or ts > latest_ts:
latest_ts = ts
latest_path = path
print("最新ファイル:", latest_path)
Python深掘りポイント
- 「比較しながら更新する」パターンは業務で非常に使える
- 最新レポート・最新ログの抽出にそのまま使える
例題③:特定の文字列を含むファイルだけ別フォルダへ移動
シナリオ
階層全体から「error」を含むログだけを抽出して error_logs に移動したい。
コード例
import os
import shutil
root = "logs"
dst = "error_logs"
os.makedirs(dst, exist_ok=True)
for current, dirs, files in os.walk(root):
for name in files:
if "error" in name.lower():
src_path = os.path.join(current, name)
dst_path = os.path.join(dst, name)
shutil.move(src_path, dst_path)
print("移動:", src_path, "→", dst_path)
Python深掘りポイント
- 再帰検索とファイル移動を組み合わせると「自動仕分け」が実現できる
- 大規模ログ管理で非常に役立つ
pathlib を使ったモダンで読みやすい再帰検索
rglob を使うと検索が直感的になる
from pathlib import Path
root = Path("project")
for p in root.rglob("*.csv"):
print("CSV:", p)
Pythonpathlib のメリット
- パス操作が直感的で読みやすい
rglob("*.csv")のようにパターン検索が簡単- サブフォルダを自動で探索してくれる
再帰検索を安全かつ効率的に行うための考え方
- ファイルかフォルダかを必ず判定する
- 大文字小文字の揺れを吸収するために
lower()を使う - 大規模フォルダでは
os.walk()の方が高速 - パターン検索が必要なら
pathlib.rglob()が便利 - 検索結果をリストに保存して後でまとめて処理する
再帰検索は「階層構造を丸ごと扱う」ための基礎であり、業務自動化の幅を大きく広げる技術です。
