Python pathlibでファイル一覧を取得する方法(glob・iterdir完全ガイド)
目次
iterdir() – ディレクトリの直下ファイル一覧
基本的な使い方
from pathlib import Path
# 現在のディレクトリの内容を取得
current_dir = Path('.')
for item in current_dir.iterdir():
print(item)
# 指定したディレクトリの内容を取得
data_dir = Path('data')
if data_dir.exists() and data_dir.is_dir():
for item in data_dir.iterdir():
print(item)
ファイルとディレクトリを区別して取得
from pathlib import Path
def list_directory_contents(dir_path):
"""ディレクトリの内容をファイルとフォルダに分けて表示"""
path = Path(dir_path)
if not path.is_dir():
print('指定されたパスはディレクトリではありません')
return
files = []
directories = []
for item in path.iterdir():
if item.is_file():
files.append(item.name)
elif item.is_dir():
directories.append(item.name)
print('ディレクトリ:', directories)
print('ファイル:', files)
# 使用例
list_directory_contents('.')
glob() – パターンマッチングでファイル検索
基本的なワイルドカード検索
from pathlib import Path
# 現在のディレクトリからPythonファイルを検索
current_dir = Path('.')
python_files = list(current_dir.glob('*.py'))
for file in python_files:
print(file)
# テキストファイルを検索
text_files = list(current_dir.glob('*.txt'))
print(f'テキストファイル数: {len(text_files)}')
再帰的検索(rglob)
from pathlib import Path
# 全てのサブディレクトリからPythonファイルを検索
root_dir = Path('.')
all_python_files = list(root_dir.rglob('*.py'))
print(f'全Pythonファイル数: {len(all_python_files)}')
# 特定の名前のファイルを再帰的に検索
config_files = list(root_dir.rglob('config.json'))
for config in config_files:
print(config)
高度なパターンマッチング
from pathlib import Path
base_dir = Path('.')
# 複数の拡張子を検索
for pattern in ['*.py', '*.txt', '*.json']:
files = list(base_dir.glob(pattern))
print(f'{pattern}: {len(files)}件')
# 文字数指定のパターン
three_char_files = list(base_dir.glob('???.txt'))
print('3文字のtxtファイル:', three_char_files)
# 文字範囲指定
numbered_files = list(base_dir.glob('file[0-9].txt'))
print('file0.txt〜file9.txtのファイル:', numbered_files)
実用的な使用例
ファイルタイプ別の統計情報
from pathlib import Path
from collections import defaultdict
def analyze_directory(dir_path):
"""ディレクトリ内のファイルタイプ別統計"""
path = Path(dir_path)
stats = defaultdict(list)
# 再帰的に全ファイルを検索
for file_path in path.rglob('*'):
if file_path.is_file():
extension = file_path.suffix.lower()
if not extension:
extension = '(拡張子なし)'
stats[extension].append(file_path)
# 結果を表示
for ext, files in sorted(stats.items()):
total_size = sum(f.stat().st_size for f in files)
print(f'{ext}: {len(files)}件, {total_size:,}バイト')
# 使用例
analyze_directory('.')
最近更新されたファイルの検索
from pathlib import Path
from datetime import datetime, timedelta
def find_recent_files(dir_path, days=7):
"""指定日数以内に更新されたファイルを検索"""
path = Path(dir_path)
cutoff_time = datetime.now().timestamp() - (days * 24 * 60 * 60)
recent_files = []
for file_path in path.rglob('*'):
if file_path.is_file() and file_path.stat().st_mtime > cutoff_time:
recent_files.append(file_path)
return sorted(recent_files, key=lambda x: x.stat().st_mtime, reverse=True)
# 使用例
recent = find_recent_files('.', days=3)
for file in recent[:10]: # 最新10件
mod_time = datetime.fromtimestamp(file.stat().st_mtime)
print(f'{file.name}: {mod_time.strftime("%Y-%m-%d %H:%M")}')
大きなファイルの検索
from pathlib import Path
def find_large_files(dir_path, min_size_mb=10):
"""指定サイズ以上のファイルを検索"""
path = Path(dir_path)
min_size_bytes = min_size_mb * 1024 * 1024
large_files = []
for file_path in path.rglob('*'):
if file_path.is_file():
size = file_path.stat().st_size
if size >= min_size_bytes:
large_files.append((file_path, size))
# サイズでソート
large_files.sort(key=lambda x: x[1], reverse=True)
return large_files
# 使用例
large_files = find_large_files('.', min_size_mb=5)
for file_path, size in large_files[:5]: # 上位5件
size_mb = size / (1024 * 1024)
print(f'{file_path.name}: {size_mb:.1f}MB')
重複ファイルの検索
from pathlib import Path
import hashlib
from collections import defaultdict
def find_duplicate_files(dir_path):
"""重複ファイルを検索"""
path = Path(dir_path)
hash_to_files = defaultdict(list)
for file_path in path.rglob('*'):
if file_path.is_file():
# ファイルのハッシュ値を計算
hash_md5 = hashlib.md5()
try:
with file_path.open('rb') as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
file_hash = hash_md5.hexdigest()
hash_to_files[file_hash].append(file_path)
except (PermissionError, OSError):
continue
# 重複ファイルのみ抽出
duplicates = {k: v for k, v in hash_to_files.items() if len(v) > 1}
return duplicates
# 使用例
duplicates = find_duplicate_files('.')
for hash_value, files in duplicates.items():
print(f'重複グループ (ハッシュ: {hash_value[:8]}...):')
for file in files:
print(f' {file}')
条件付きファイル検索
複数条件での絞り込み
from pathlib import Path
def find_files_by_criteria(dir_path, extension=None, min_size=None, max_size=None):
"""複数条件でファイルを検索"""
path = Path(dir_path)
results = []
pattern = f'*.{extension}' if extension else '*'
for file_path in path.rglob(pattern):
if not file_path.is_file():
continue
# サイズ条件をチェック
file_size = file_path.stat().st_size
if min_size and file_size < min_size:
continue
if max_size and file_size > max_size:
continue
results.append(file_path)
return results
# 使用例
# 1KB以上10KB以下のPythonファイル
py_files = find_files_by_criteria('.', extension='py',
min_size=1024, max_size=10240)
for file in py_files:
print(file)
除外パターンでの検索
from pathlib import Path
def find_files_excluding(dir_path, exclude_patterns=None):
"""特定パターンを除外してファイルを検索"""
path = Path(dir_path)
exclude_patterns = exclude_patterns or []
results = []
for file_path in path.rglob('*'):
if not file_path.is_file():
continue
# 除外パターンをチェック
should_exclude = False
for pattern in exclude_patterns:
if file_path.match(pattern):
should_exclude = True
break
if not should_exclude:
results.append(file_path)
return results
# 使用例
# __pycache__や.gitディレクトリを除外
files = find_files_excluding('.', exclude_patterns=[
'*/__pycache__/*',
'*/.git/*',
'*.pyc'
])
print(f'除外後のファイル数: {len(files)}')
パフォーマンス最適化
大量ファイル処理の最適化
from pathlib import Path
import os
def fast_file_count(dir_path, extension=None):
"""高速なファイル数カウント"""
path = Path(dir_path)
count = 0
try:
# os.scandirを使用してより高速に処理
with os.scandir(path) as entries:
for entry in entries:
if entry.is_file():
if extension is None:
count += 1
elif entry.name.endswith(f'.{extension}'):
count += 1
except (PermissionError, FileNotFoundError):
return 0
return count
# 使用例
py_count = fast_file_count('.', 'py')
print(f'Pythonファイル数: {py_count}')
エラーハンドリング
安全なディレクトリ検索
from pathlib import Path
def safe_directory_scan(dir_path):
"""エラーハンドリング付きディレクトリスキャン"""
path = Path(dir_path)
if not path.exists():
print(f'パスが存在しません: {path}')
return []
if not path.is_dir():
print(f'ディレクトリではありません: {path}')
return []
files = []
try:
for item in path.iterdir():
try:
if item.is_file():
files.append(item)
except (PermissionError, OSError) as e:
print(f'アクセスエラー {item}: {e}')
continue
except PermissionError:
print(f'ディレクトリへのアクセス権限がありません: {path}')
return files
# 使用例
files = safe_directory_scan('/protected/directory')
print(f'アクセス可能なファイル数: {len(files)}')
まとめ
pathlibのglob()、rglob()、iterdir()を使うことで、柔軟で強力なファイル検索が可能になります。従来のosモジュールと比べて、より読みやすく直感的なコードが書けるのが特徴です。大量ファイルを扱う場合は、適切なエラーハンドリングとパフォーマンス最適化を心がけましょう。
■「らくらくPython塾」が切り開く「呪文コーディング」とは?
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座


