Python で再帰的にディレクトリ内のファイルを取得する(glob, rglob)

ディレクトリ内のファイルを再帰的に取得するには glob モジュールや pathlibrglob() メソッドを使う。

glob.glob で再帰的に取得する

glob.glob()** パターンと recursive=True を指定すると、サブディレクトリを含めて再帰的にファイルを検索できる。

import glob

# すべての .txt ファイルを再帰的に取得
files = glob.glob('mydir/**/*.txt', recursive=True)

for f in files:
    print(f)

** はゼロ個以上のディレクトリにマッチする。recursive=True を忘れると ** が機能しないので注意が必要だ。

pathlib.Path.rglob を使う方法

pathlib では rglob() メソッドで再帰検索ができる。

from pathlib import Path

# すべての .py ファイルを再帰的に取得
for path in Path('mydir').rglob('*.py'):
    print(path)

rglob('*.py')glob('**/*.py') と同じ意味だが、より簡潔に書ける。

すべてのファイルを取得する

拡張子を問わずすべてのファイルを取得するには * を使う。

from pathlib import Path

for path in Path('mydir').rglob('*'):
    if path.is_file():
        print(path)

rglob('*') はディレクトリも含めて返すため、ファイルだけが必要な場合は is_file() でフィルタリングする。

os.walk を使う方法

os.walk() はディレクトリを再帰的に走査し、各ディレクトリのパス・サブディレクトリ・ファイルをタプルで返す。

import os

for dirpath, dirnames, filenames in os.walk('mydir'):
    for filename in filenames:
        filepath = os.path.join(dirpath, filename)
        print(filepath)

os.walk() は細かい制御が必要な場合に便利だ。特定のディレクトリをスキップしたい場合は dirnames を操作する。

import os

for dirpath, dirnames, filenames in os.walk('mydir'):
    # __pycache__ ディレクトリをスキップ
    dirnames[:] = [d for d in dirnames if d != '__pycache__']
    
    for filename in filenames:
        print(os.path.join(dirpath, filename))