Skip to content

Instantly share code, notes, and snippets.

@mtimkovich
Last active December 13, 2016 22:58
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 mtimkovich/af69f80e92947d0ee35d86752fefbdc5 to your computer and use it in GitHub Desktop.
Save mtimkovich/af69f80e92947d0ee35d86752fefbdc5 to your computer and use it in GitHub Desktop.
Mass rename files with python
#!/usr/bin/env python3
import argparse
from glob import glob
import os
import re
import sys
def parse_args():
parser = argparse.ArgumentParser('Rename files using regex')
parser.add_argument('regex',
help="regex to apply to files (e.g. 's/regex/replace/')")
parser.add_argument('files', nargs='+',
help='files to modify')
parser.add_argument('-n', '--dry-run', action='store_true',
help="print outcome, don't rename")
parser.add_argument('-v', '--verbose', action='store_true',
help='verbose output')
parser.add_argument('-x', '--ignore-ext', action='store_true',
help='ignore file extensions')
parser.add_argument('-i', '--interactive', action='store_true',
help='prompt before overwriting')
return parser.parse_args()
def confirm(msg):
return input('{} [Y/n] '.format(msg)).lower() == 'y'
def error(*msg):
print(*msg, file=sys.stderr)
args = parse_args()
split = args.regex.split('/')
if len(split) != 4 or split[0] != 's':
error("Invalid regex: '{}'".format(args.regex))
sys.exit(1)
_, search, replace, flags = split
flags = re.I if flags == 'i' else 0
# This bit is for Windows, where wildcards aren't expanded
if any('*' in f for f in args.files):
files = []
for f in args.files:
files += glob(f)
else:
files = args.files
for f in files:
if not os.path.exists(f):
error("No such file or directory: '{}'".format(f))
continue
if args.ignore_ext:
f, ext = os.path.splitext(f)
output = re.sub(search, replace, f, flags=flags)
# Add extension back
if args.ignore_ext:
f += ext
output += ext
# No change, don't care
if f == output:
continue
# Check for conflicts in interactive mode
if (args.interactive and
not args.dry_run and
os.path.exists(output) and
not confirm('overwrite {}?'.format(output))):
continue
if args.dry_run or args.verbose:
print('{} -> {}'.format(f, output))
if not args.dry_run:
os.rename(f, output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment