This Python script takes a directory path and then proceeds to scan every file and sub-directory within, looking for any filenames or directory names that exceed a specified length. Once found, the script truncates these names to fit within the desired length and appends an ellipsis (e.g., ...
) to indicate the truncation. The beauty of this script lies in its configurability and the safety features embedded within it.
Note: Using this script will lose information (because the new filenames will be shorter and any important information in the rest of the filename will be lost forever). Additionally, it might lose information in other ways. Even though we have tested it carefully, it might still destroy your data in unexpected ways. Use a
How to use
The script provides the following command line options:
usage: FixLongFilenames.py [-h] [-n LENGTH] [--ellipsis ELLIPSIS] [--dry] directory Shorten long filenames and directory names. positional arguments: directory The directory to process. options: -h, --help show this help message and exit -n LENGTH, --length LENGTH The maximum allowable length for directory or file names. --ellipsis ELLIPSIS The ellipsis to use when shortening. --dry Dry run mode, only log what would be renamed without actual renaming.
Source code
#!/usr/bin/env python3 import os import argparse def shorten_path(path, max_length, ellipsis, dry_run): if os.path.isdir(path): base_name = os.path.basename(path) if len(base_name) > max_length: new_name = base_name[:max_length] + ellipsis new_path = os.path.join(os.path.dirname(path), new_name) if not os.path.exists(new_path): if dry_run: print(f"[DRY RUN] Directory would be renamed: {path} -> {new_name}") else: os.rename(path, new_path) print(f"Renamed directory: {path} -> {new_name}") return new_path else: base_name, ext = os.path.splitext(os.path.basename(path)) if len(base_name) > max_length: new_name = base_name[:max_length] + ellipsis + ext new_path = os.path.join(os.path.dirname(path), new_name) if not os.path.exists(new_path): if dry_run: print(f"[DRY RUN] File would be renamed: {path} -> {new_name}") else: os.rename(path, new_path) print(f"Renamed file: {path} -> {new_name}") return new_path return path def iterate_and_shorten(directory, max_length, ellipsis, dry_run): for root, dirs, files in os.walk(directory, topdown=False): for dname in dirs: dpath = os.path.join(root, dname) shortened_path = shorten_path(dpath, max_length, ellipsis, dry_run) dirs[dirs.index(dname)] = os.path.basename(shortened_path) for fname in files: fpath = os.path.join(root, fname) shorten_path(fpath, max_length, ellipsis, dry_run) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Shorten long filenames and directory names.") parser.add_argument('directory', help="The directory to process.") parser.add_argument('-n', '--length', type=int, default=100, help="The maximum allowable length for directory or file names.") parser.add_argument('--ellipsis', default="...", help="The ellipsis to use when shortening.") parser.add_argument('--dry', action="store_true", help="Dry run mode, only log what would be renamed without actual renaming.") args = parser.parse_args() iterate_and_shorten(args.directory, args.length, args.ellipsis, args.dry)