Files

83 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Directory analyzer: counts files, sizes, and types."""
import os
import json
import sys
from pathlib import Path
from collections import Counter
def analyze_dir(path: str) -> dict:
"""Analyze a directory and return statistics."""
p = Path(path)
if not p.exists():
return {"error": f"Path does not exist: {path}"}
stats = {
"path": str(p.resolve()),
"total_files": 0,
"total_dirs": 0,
"total_size_bytes": 0,
"file_extensions": Counter(),
"largest_file": {"path": None, "size": 0},
"smallest_file": {"path": None, "size": float('inf')},
}
for item in p.rglob('*'):
if item.is_file():
stats["total_files"] += 1
size = item.stat().st_size
stats["total_size_bytes"] += size
ext = item.suffix.lower() if item.suffix else "(no extension)"
stats["file_extensions"][ext] += 1
if size > stats["largest_file"]["size"]:
stats["largest_file"] = {"path": str(item), "size": size}
if size < stats["smallest_file"]["size"]:
stats["smallest_file"] = {"path": str(item), "size": size}
elif item.is_dir():
stats["total_dirs"] += 1
if stats["smallest_file"]["path"] is None:
stats["smallest_file"] = {"path": None, "size": 0}
stats["file_extensions"] = dict(stats["file_extensions"])
stats["total_size_human"] = f"{stats['total_size_bytes'] / 1024:.2f} KB"
return stats
def summary_report(path: str) -> str:
"""Generate a human-readable summary."""
result = analyze_dir(path)
if "error" in result:
return f"Error: {result['error']}"
lines = [
f"Directory: {result['path']}",
f"Total files: {result['total_files']}",
f"Total directories: {result['total_dirs']}",
f"Total size: {result['total_size_human']} ({result['total_size_bytes']:,} bytes)",
"",
"Top 5 extensions by count:",
]
sorted_exts = sorted(result['file_extensions'].items(), key=lambda x: -x[1])[:5]
for ext, count in sorted_exts:
lines.append(f" {ext or '(none)'}: {count}")
lines.append("")
lines.append(f"Largest file: {result['largest_file']['path']}")
lines.append(f" Size: {result['largest_file']['size']:,} bytes")
lines.append("")
lines.append(f"Smallest file: {result['smallest_file']['path']}")
lines.append(f" Size: {result['smallest_file']['size']} bytes")
return "\n".join(lines)
if __name__ == "__main__":
target = sys.argv[1] if len(sys.argv) > 1 else "/etc"
if "--json" in sys.argv:
result = analyze_dir(target)
print(json.dumps(result, indent=2))
else:
print(summary_report(target))