Himan Himan - 2 months ago 5
Python Question

Replace specific text with a block of text

I am trying to replace a small section of text with a block of text. I am hoping that this block of text will be replaced using replace function of python. I would have really like to use

sed
to get this job, but I am on windows machine. Anyway here is my script, not sure why the block of text isn't being replaced.

# Change the current working directory to IDX location
import os
print os.getcwd()
os.chdir(##location of my text files##)
print os.getcwd()

#Read file names

com_line=raw_input("File name please:")
contents=[]
strs = '#DREFIELD IDOL_SOURCE="idol source"\n#DREFIELD IDOL_TAXONOMY="taxonomy data"\n #DREFIELD IDOL_CATEGORY="IDOL_CATEGORY"\n #DREFIELD IDOL_PROMOTION="idol_promotion"\n #DREFIELD IDOL_PROMOTION_TERM="IDOL_PROMOTION_TERM"\n #DREFIELD IDOL_WHATSNEW="IDOL_WHATSNEW"\n #DREFIELD IDOL_SUMMARY="IDOL_SUMMARY"\n #DREFIELD IDOL_URL="IDOL_URL DATA"\n #DREFIELD IDOL_FORMNUMBER="IDOL_FORMNUMBER"\n #DREFIELD IDOL_DESCRIPTION="IDOL_DESCRIPTION DATA"\n#DRESECTION 0\n'
with open(com_line) as f:
contents.append(f.readlines())
f.close

#Writing to file
f2 = open("test.idx", 'w')

for content in contents:
for s in content:
if s == '#DRESECTION 0\n':
s.replace("#DRESECTION 0\n", strs)
f2.write("%s" % s)
f2.close


I tested this code, and it is entering the conditional statement as well. Just wondering why is the needful text
#DRESECTION 0\n
not getting replaced with
strs
? Also I am looking to do this operation of large text files worth few gigs. Is there a better way of reading large text files in python?

Answer

Stings in Python are immutable. Once a string object has been created, it can't be modified. You can however create a new string based on the old one.

When you are calling s.replace, it doesn't modify s in place, because that's not possible. Instead, the str.replace method returns a new string. You could do s = s.replace(...) and it should work. However, there's no point in replacing the whole contents of one string with another string when you could just rebind the name to the new string.

I suggest using:

    if s == '#DRESECTION 0\n':
        s = strs
    f2.write(s)

I also changed the write call. There's no need to use string substitution here, since you want to write the whole string (and nothing extra). Just pass s as the argument.

There are a few other minor issues with your code:

For instance, you're not calling the close methods on your files, only naming them. You need f2.close() if you want to actually close the file. But you don't actually need to do that for f, since the with statement you're using will close the file automatically (you should probably use a with for f2 and not bother with the manual close call).

There also doesn't seem to be much need contents to be a nested list (with just one item in the outer list). You probably want to do contents = f.readlines() rather than appending the list of lines to an initially empty list. That will let you get rid of one of the loops in the later code.