Python script to distribute files in a folder into multiple sub-directories

This Python script will distribute files in a folder into multiple sub-directories, ensuring that approximately the same number of files is in each sub-folder. This allows handling directories with millions of files even with tools which have trouble with large directories.

#!/usr/bin/env python3
import os
import shutil
from math import ceil
import argparse
from tqdm import tqdm  # Neue Import-Zeile

def main():
    parser = argparse.ArgumentParser(description="Distribute files from a directory into subdirectories.")
    parser.add_argument("directory", type=str, help="Path to the directory containing files.")
    parser.add_argument("-n", "--num-folders", type=int, default=10, help="Number of subdirectories to create.")
    parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making any changes.")
    
    args = parser.parse_args()

    directory = args.directory
    num_folders = args.num_folders
    dry_run = args.dry_run

    if num_folders <= 0:
        print("Error: The number of folders must be a positive integer.")
        return

    if not os.path.isdir(directory):
        print(f"Error: {directory} is not a valid directory.")
        return

    # List and sort files in the directory
    files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
    files.sort()

    if not files:
        print("No files found in the directory.")
        return

    # Calculate files per folder
    files_per_folder = ceil(len(files) / num_folders)

    # Create subdirectories and distribute files
    total_operations = len(files)  # Gesamtzahl der zu bewegenden Dateien
    with tqdm(total=total_operations, desc="Moving files") as pbar:
        for i in range(1, num_folders + 1):
            subdir = os.path.join(directory, str(i))
            if not dry_run:
                os.makedirs(subdir, exist_ok=True)
            else:
                print(f"Would create directory: {subdir}")

            start_index = (i - 1) * files_per_folder
            end_index = start_index + files_per_folder
            files_to_move = files[start_index:end_index]

            for file in files_to_move:
                src = os.path.join(directory, file)
                dest = os.path.join(subdir, file)
                if not dry_run:
                    shutil.move(src, dest)
                else:
                    print(f"Would move {src} to {dest}")
                pbar.update(1)  # Fortschrittsbalken nach jeder Datei aktualisieren

    if not dry_run:
        print(f"Files successfully distributed into {num_folders} folders.")
    else:
        print("Dry run completed. No files were actually moved.")

if __name__ == "__main__":
    main()