Tools - python - file sizes

30 July 2025 - Written by ML

Highlights

  • Terminal tool to generate a list of files from directory and subdirectory with their sizes and location from terminal.

  • Terminal tool to generate a list of pdf from directory and subdirectory ranked by filesize.

Aim

  • Rapid understanding of folder contents

  • Code has been generated with considerable support from various ai including Kimi.ai, Mistral.ai, Cursor.

Method

  • set out goal. Ask ai to write code. Implement in cursor. Have cursor refine and improve.

Script

1. Generate file list

import os
import sys
import csv
from datetime import datetime

def get_files_by_size(directory):
    file_sizes = []

    for root, _, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                size = os.path.getsize(file_path)
                file_sizes.append((file_path, size))
            except (OSError, PermissionError):
                # Skip files we can't access
                continue

    # Sort files by size in descending order
    file_sizes.sort(key=lambda x: x[1], reverse=True)

    return file_sizes

def format_size(size_bytes):
    """Convert bytes to human readable format"""
    if size_bytes == 0:
        return "0 B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024.0
        i += 1
    
    return f"{size_bytes:.1f} {size_names[i]}"

def save_to_csv(files_by_size, output_file):
    """Save file size results to CSV"""
    with open(output_file, 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        
        # Write header
        writer.writerow(['Rank', 'Size (bytes)', 'Size (formatted)', 'File Path', 'Directory'])
        
        # Write data
        for i, (file_path, size) in enumerate(files_by_size, 1):
            directory = os.path.dirname(file_path)
            formatted_size = format_size(size)
            writer.writerow([i, size, formatted_size, file_path, directory])

def main():
    if len(sys.argv) != 2:
        print("Usage: python file_size.py <directory_path>")
        print("Example: python file_size.py '/path/to/directory'")
        sys.exit(1)
    
    directory = sys.argv[1]
    
    if not os.path.exists(directory):
        print(f"Error: Directory '{directory}' does not exist.")
        sys.exit(1)
    
    if not os.path.isdir(directory):
        print(f"Error: '{directory}' is not a directory.")
        sys.exit(1)
    
    print(f"Scanning directory: {directory}")
    print("-" * 50)
    
    files_by_size = get_files_by_size(directory)
    
    if not files_by_size:
        print("No files found in the directory.")
        return
    
    # Display results
    for i, (file_path, size) in enumerate(files_by_size, 1):
        formatted_size = format_size(size)
        print(f"{i:3d}. {formatted_size:>10} - {file_path}")
    
    # Save to CSV
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    dir_name = os.path.basename(directory.rstrip('/'))
    csv_filename = f"file_sizes_{dir_name}_{timestamp}.csv"
    
    try:
        save_to_csv(files_by_size, csv_filename)
        print(f"\nResults saved to: {csv_filename}")
        print(f"Total files found: {len(files_by_size)}")
    except Exception as e:
        print(f"\nError saving CSV file: {e}")

if __name__ == "__main__":
    main()

2. By pdf generate file list

#!/usr/bin/env python3
"""
pdf_page_counter.py
Recursively find all PDF files, count pages, and print
the list ordered from highest page-count to lowest.
Also saves results to CSV file.
"""

import os
import sys
import csv
from pathlib import Path
from datetime import datetime

# Third-party dependency:  pip install PyPDF2
from PyPDF2 import PdfReader

def count_pages(pdf_path: Path) -> int:
    """Return the number of pages in a PDF."""
    try:
        with open(pdf_path, "rb") as f:
            reader = PdfReader(f)
            return len(reader.pages)
    except Exception as e:
        print(f"WARNING: could not open {pdf_path}: {e}", file=sys.stderr)
        return 0

def format_filesize(size_bytes: int) -> str:
    """Format file size in human readable format."""
    if size_bytes == 0:
        return "0 B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    import math
    i = int(math.floor(math.log(size_bytes, 1024)))
    p = math.pow(1024, i)
    s = round(size_bytes / p, 2)
    return f"{s} {size_names[i]}"

def main(root_dir: Path):
    print(f"Starting scan of directory: {root_dir}", file=sys.stderr)
    
    if not root_dir.is_dir():
        print(f"{root_dir} is not a directory", file=sys.stderr)
        sys.exit(1)

    pdf_list = []
    pdf_count = 0

    # Walk the tree
    for dirpath, _dirnames, filenames in os.walk(root_dir):
        for fname in filenames:
            if fname.lower().endswith(".pdf"):
                pdf_count += 1
                if pdf_count % 10 == 0:
                    print(f"Processing PDF #{pdf_count}...", file=sys.stderr)
                full_path = Path(dirpath, fname).resolve()
                pages = count_pages(full_path)
                file_size = full_path.stat().st_size
                pdf_list.append((pages, file_size, str(full_path)))

    print(f"Found {len(pdf_list)} PDF file(s)\n")
    
    # Sort by file size descending (not page count)
    pdf_list.sort(key=lambda t: t[1], reverse=True)

    # Generate CSV filename with timestamp
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    csv_filename = f"pdf_file_sizes_{timestamp}.csv"
    
    # Save to CSV
    with open(csv_filename, 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['Rank', 'File Size (bytes)', 'File Size (formatted)', 'Pages', 'Filename', 'Directory'])
        
        for rank, (pages, file_size, full_path) in enumerate(pdf_list, 1):
            path_obj = Path(full_path)
            filename = path_obj.name
            directory = str(path_obj.parent)
            formatted_size = format_filesize(file_size)
            
            writer.writerow([rank, file_size, formatted_size, pages, filename, directory])
    
    print(f"Results saved to: {csv_filename}")
    print()

    # Print nicely to console
    for rank, (pages, file_size, full_path) in enumerate(pdf_list, 1):
        path_obj = Path(full_path)
        filename = path_obj.name
        formatted_size = format_filesize(file_size)
        print(f"{rank:>3}. {formatted_size:>10}  {pages:>6} pages  {filename}")

if __name__ == "__main__":
    # Accept an optional directory argument; default to "."
    root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.cwd()
    main(root)