Trimming Down Long Directory and File Names using Python
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)