Skip to content

Instantly share code, notes, and snippets.

@louisswarren
Created March 6, 2017 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louisswarren/0b543de3223169fb1a2ce5cfdbb22d1e to your computer and use it in GitHub Desktop.
Save louisswarren/0b543de3223169fb1a2ce5cfdbb22d1e to your computer and use it in GitHub Desktop.
Rename files in a directory to have ordinal prefixes, sorted by US date (mm-dd-yyyy) in filename
import os
import re
US_DATE_REGEX = re.compile(r'(\d\d)-(\d\d)-(\d\d\d\d)')
def parse_name(name):
match = US_DATE_REGEX.search(os.path.basename(name))
if match:
month, day, year = map(int, match.groups())
return (year, month, day)
def sort_names(filenames):
sortable = []
for name in filenames:
ordinal = parse_name(name)
if ordinal:
sortable.append((ordinal, name))
return [name for _, name in sorted(sortable)]
def safe_rename(src, dest, undo_file=None):
if os.name == 'nt':
move_cmd = 'move'
else:
move_cmd = 'mv'
escaped_src = src.replace('"', '\\"')
escaped_dest = dest.replace('"', '\\"')
if undo_file:
undo_file.write('{} '.format(move_cmd))
undo_file.write('"{}" "{}"\n'.format(escaped_dest, escaped_src))
os.rename(src, dest)
def rename_enumerated(filenames, undo_file):
for n, name in enumerate(sort_names(filenames)):
new_basename = '{}. {}'.format(n + 1, os.path.basename(name))
new_name = os.path.join(os.path.dirname(name), new_basename)
safe_rename(name, new_name, undo_file)
def main(d):
if os.name == 'nt':
undo_script = 'undo.bat'
else:
undo_script = 'undo.sh'
undo_path = os.path.join(d, undo_script)
filenames = [os.path.join(d, filename) for filename in os.listdir(d)]
with open(undo_path, 'w') as undo_file:
rename_enumerated(sort_names(filenames), undo_file)
if __name__ == '__main__':
d = input("Which dir?\n")
main(d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment