Skip to content

Instantly share code, notes, and snippets.

@DeeeeLAN
Created February 22, 2024 04:53
Show Gist options
  • Save DeeeeLAN/091d28f935cad5f27b892ad99fd76064 to your computer and use it in GitHub Desktop.
Save DeeeeLAN/091d28f935cad5f27b892ad99fd76064 to your computer and use it in GitHub Desktop.
Fix filenames on a case-sensitive filesystem that would cause collisions on a case-insensitive system (useful for syncthing between Linux and macOS, for example)
import os
import collections
import sys
def rename_case_insensitive_duplicates(directory):
count = 0
for dirpath, dirs, files in os.walk(directory):
# Create dictionaries for filenames and dirnames
filenames = collections.defaultdict(list)
dirnames = collections.defaultdict(list)
for name in files:
filenames[name.lower()].append(os.path.join(dirpath, name))
for name in dirs:
dirnames[name.lower()].append(os.path.join(dirpath, name))
# Rename files with the same lowercase filename
for name_list in filenames.values():
if len(name_list) > 1:
for i, name in enumerate(name_list):
base, ext = os.path.splitext(name)
print(f'renaming {name} to {base}_{i}{ext}')
os.rename(name, f"{base}_{i}{ext}")
count += 1
# Rename directories with the same lowercase dirname
for name_list in dirnames.values():
if len(name_list) > 1:
for i, name in enumerate(name_list):
base = os.path.basename(name)
dir = os.path.dirname(name)
print(f'renaming {name} to {base}_{i}')
os.rename(name, os.path.join(dir, f"{base}_{i}"))
count += 1
print(f"Renamed {count} files and directories")
# Get the directory path from the command line arguments
directory = sys.argv[1]
# Call the function on the directory you want to scan
rename_case_insensitive_duplicates(directory)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment