# regexplace: regular expression search and replace# Stefano Spinucci# 2006-02-07 (rev 4)# thanks to roadrunner.py# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52553# for some ideas and some code# tested with python 2.3.5importsys,os,re,string# pupulate and return 'fileslist[]' with all files inside 'dir' matching 'regx'defmake_files_list(dir,regx):# if dir is not a directory, exit with errorifnotos.path.isdir(dir):sys.exit(dir+' is not a valid dir to walk !!!')# compile the search regexpcregex=re.compile(regx)# initialize the file listfileslist=[]# loop on all files and select files matching 'regx'forroot,dirs,filesinos.walk(dir):fornameinfiles:ifcregex.search(name):path=os.path.join(root,name)fileslist.append(path)# return the file listreturnfileslist[:]# in all files in 'fileslist' search the regexp 'searchregx' and replace# with 'replacestring'; real substitution in files only if 'simulation' = 0;# real substitution may also be step by step (if 'stepbystep' = 1)defreplace_in_files(fileslist,searchregx,replacestring,simulation,stepbystep):# compile regexpcregex=re.compile(searchregx)# print message to the userifsimulation==1:print'\nReplaced (simulation):\n'else:print'\nReplaced:\n'# loop on all filesforxfileinfileslist:# initialize the replace flagreplaceflag=0# open file for read readlines=open(xfile,'r').readlines()# intialize the list counterlistindex=-1# search and replace in current file printing to the user changed linesforcurrentlineinreadlines:# increment the list counterlistindex=listindex+1# if the regexp is foundifcregex.search(currentline):# make the substitutionf=re.sub(searchregx,replacestring,currentline)# print the current filename, the old string and the new stringprint'\n'+xfileprint'- '+currentline,ifcurrentline[-1:]!='\n':print'\n',print'+ '+f,iff[-1:]!='\n':print'\n',# if substitution is realifsimulation==0:# if substitution is step by stepifstepbystep==1:# ask user if the current line must be replacedquestion=raw_input('write(Y), skip (n), quit (q) ? ')question=string.lower(question)# if quitifquestion=='q':sys.exit('\ninterrupted by the user !!!')# if skipelifquestion=='n':pass# if writeelse:# update the whole file variable ('readlines')readlines[listindex]=freplaceflag=1# if substitution is not step by stepelse:# update the whole file variable ('readlines')readlines[listindex]=freplaceflag=1# if some text was replaced# overwrite the original fileifreplaceflag==1:# open the file for writting write_file=open(xfile,'w')# overwrite the file forlineinreadlines:write_file.write(line)# close the filewrite_file.close()# main functiondefmain():# if parameters are wrong, exit with erroriflen(sys.argv)<5:print'\nUsage:'print'python regexplace.py dirname files-regexp search-regexp replace-string'sys.exit(1)# ask user for simulated execution or real substitutionprint'\nyou are replacing %s with %s in %s'%(sys.argv[3],sys.argv[4],sys.argv[2])question1=raw_input('continue with real substitution (y/N) ? ')question1=string.lower(question1)# if user selected real substitution, ask user if execution must be step by stepifquestion1=='y':question2=raw_input('\nsubstitute step by step (Y/n) ? ')question2=string.lower(question2)# make the file listfileslist=make_files_list(sys.argv[1],sys.argv[2])# if real substitutionifquestion1=='y':# if step by stepifquestion2!='n':replace_in_files(fileslist,sys.argv[3],sys.argv[4],0,1)# if not step by stepelse:replace_in_files(fileslist,sys.argv[3],sys.argv[4],0,0)# if simulated executionelse:replace_in_files(fileslist,sys.argv[3],sys.argv[4],1,0)if__name__=='__main__':main()

1 comment

For a better user interaction. There are many python scripts in Gentoo Linux that just require to press a key to answer a question like (Y/n); really great to answer a lot of questions like you may have in the step-by-step mode of regexplace.py !