Find and replace is appending when run more than once ...

MRAB google at mrabarnett.plus.com
Sat Apr 18 00:16:20 CEST 2009


Paul.Scipione at aps.com wrote:
> Hello,
>  
> I grabbed some sample code from the web and put together this python 
> script which searches all subdirectories for a specific file type, then 
> replaces a string with a new one.  Out of curiosity I ran it again.  
> Here's what happens (this also happens for the files I am looking to 
> replace OutputPath=Z:\ with OutputPath=Z:\DXF):
>  
> 1st run:  replaces OutputPath=Z:\ with OutputPath=Z:\CSV )
> 2nd run: replaces OutputPath=Z:\CSV with OutputPath=Z:\CSV\CSV
> 3rd run:  replaces OutputPath=Z:\CSV\CSV with OutputPath=Z:\CSV\CSV\CSV
> And so on.
>  
> I cant figure out why it's doing this if I am searching a certain string 
> value and replacing it.  I am also perplexed on why it is only adding 
> the "CSV" each time rather than the full string.  What I want it to do 
> is only replace once.  Next time I run it it shouldn't do anything.
>  
> import fnmatch,os,sys
>  
> mydir = 'C:\\!DOMSExtractor'
> findStr = 'OutputPath=Z:\\'
>  
> def replaceStringInFile(findStr,replStr,filePath):
>     tempName=filePath+'~~~'
>     input = open(filePath)
>     output = open(tempName,'w')
>  
>     for s in input:
>         print findStr
>         print replStr
>         output.write(s.replace(findStr,replStr))

This is replacing 'OutputPath=Z:\\' with 'OutputPath=Z:\\CSV\\' because
findStr is 'OutputPath=Z:\\' and replStr is 'OutputPath=Z:\\CSV\\'.
Unfortunately replStr starts with findStr, so if you had:

     'OutputPath=Z:\\foo'

then you would get:

     'OutputPath=Z:\\CSV\\foo'

Notice that this string still contains 'OutputPath=Z:\\', so doing it
again would result in:

     'OutputPath=Z:\\CSV\\CSV\\foo'

Perhaps you could do something like this:

     # Start with:
     #     'fooOutputPath=Z:\\bar'
     # or:
     #     'fooOutputPath=Z:\\CSV\\bar'

     new_s = s.replace(findStr, replStr + '*')

     # Now have:
     #     'fooOutputPath=Z:\\CSV\\*bar'
     # or:
     #     'fooOutputPath=Z:\\CSV\\*CSV\\bar'

     new_s = new_s.replace('\\*CSV', '')

     # Now have:
     #     'fooOutputPath=Z:\\CSV\\*bar'
     # or:
     #     'fooOutputPath=Z:\\CSV\\bar'

     new_s = new_s.replace('CSV\\*', 'CSV\\')

     # Now have:
     #     'fooOutputPath=Z:\\CSV\\bar'
     # or:
     #     'fooOutputPath=Z:\\CSV\\bar'

>     output.close()
>     input.close()
>     os.remove(filePath)
>     os.rename(tempName,filePath)
>     print filePath
>  
> def myfun(dummy, dirr, filess):
>     for child in filess:
>         filePath = dirr+'/'+child
>         if '.ini' == os.path.splitext(child)[1] and 
> os.path.isfile(filePath):
>             print file(filePath, 'rb').read().find(findStr)
>             if file(filePath, 'rb').read().find(findStr) <> -1:
>                 if fnmatch.fnmatch(dirr+'/'+child, '*BGExtract.ini'):
>                     
> replaceStringInFile(findStr,'OutputPath=Z:\\DXF\\',filePath)
>                 elif fnmatch.fnmatch(dirr+"/"+child, '*GISExtract.ini'):
>                     
> replaceStringInFile(findStr,'OutputPath=Z:\\CSV\\',filePath)
>  
> os.path.walk(mydir, myfun, 3)
>  



More information about the Python-list mailing list