Created
May 14, 2015 00:46
-
-
Save yig/7babd25504379e08b956 to your computer and use it in GitHub Desktop.
A command line tool for find/replace in filenames (and even paths).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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