Skip to content

Instantly share code, notes, and snippets.

@yig
Created May 14, 2015 00:46
Show Gist options
  • Save yig/7babd25504379e08b956 to your computer and use it in GitHub Desktop.
Save yig/7babd25504379e08b956 to your computer and use it in GitHub Desktop.
A command line tool for find/replace in filenames (and even paths).
#!/usr/bin/env python -OO
import sys
import os
harmful = False
overwrite = False
full_path = False
def usage():
print >> sys.stderr, "Usage:", sys.argv[0], "[--overwrite] [--fullpath] [really] replace find_string replace_string file1 ... fileN"
print >> sys.stderr, "Usage:", sys.argv[0], "[--overwrite] [--fullpath] [really] regexp find_string replace_string file1 ... fileN"
print >> sys.stderr, "Note: Unless --fullpath is specified, only the basename of the path of each file is affected."
sys.exit( -1 )
argv = list( sys.argv )
if len( argv ) == 0: usage()
## Remove the program name
del argv[0]
## Find the index of the command (replace or regexp)
cmd_index = [ i for i, val in enumerate( argv ) if val in ( 'replace', 'regexp' ) ]
if len( cmd_index ) == 0: usage()
cmd_index = cmd_index[0]
def pop_argument( arg_name ):
'''
Given an argument name 'arg_name',
removes it from the global variable 'argv' if present,
and returns whether or not it was present.
'''
global argv, cmd_index
try:
index = argv.index( arg_name, 0, cmd_index )
except ValueError:
return False
else:
del argv[ index ]
cmd_index -= 1
return True
if pop_argument( '--overwrite' ):
overwrite = True
if pop_argument( 'really' ):
harmful = True
if pop_argument( '--fullpath' ):
full_path = True
if len( argv ) < 4:
usage()
cmd = argv[0]
find_str = argv[1]
replace_str = argv[2]
files = argv[ 3: ]
def replace( in_str, find_me, replace_me ):
return in_str.replace( find_me, replace_me )
import re
def regexp( in_str, find_me, replace_me ):
return re.sub( find_me, replace_me, in_str )
if cmd == 'replace':
cmd = replace
elif cmd == 'regexp':
cmd = regexp
else:
usage()
sys.exit( -1 )
for fname in files:
## remove trailing '/'s so that we rename the directory
fname = fname.rstrip( os.path.sep )
if not os.path.exists( fname ):
print >> sys.stderr, "Error: No such file [" + fname + "]."
continue
if full_path:
new_fname = cmd( fname, find_str, replace_str )
else:
path, basename = os.path.split( fname )
new_basename = cmd( basename, find_str, replace_str )
new_fname = os.path.join( path, new_basename )
if new_fname == fname:
print 'No changes to [' + fname + '].'
continue
print 'Renaming [' + fname + '] to [' + new_fname + '].'
## 3 move the file
if os.path.exists( new_fname ):
if overwrite:
print >> sys.stderr, "Replacing already existing file [" + new_fname + "]."
else:
print >> sys.stderr, "Error: Refusing to replace already existing file [" + new_fname + "]."
continue
if harmful:
os.rename( fname, new_fname )
if not harmful:
print >> sys.stderr, "Dry run complete. If you like what you see, run with 'really'."
sys.exit( 0 )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment