Andrea
Andrea

Reputation: 73

How do I edit a text file in Python?

text = open('samiam.txt', 'r+')
keyword = " i "
keyword2 = "-i-"
replacement = " I "
replacement2 = "-I-"

for line in text:    
    if keyword in line:
        text.write(line.replace(keyword, replacement))
        print line
    elif keyword2 in line:
        text.write(line.replace(keyword2, replacement2))
        print line
    else:
        print line
text.close()

I'm not entirely sure why the text is not being written to the file. help?

Upvotes: 3

Views: 37124

Answers (4)

thiruvenkadam
thiruvenkadam

Reputation: 4260

It will be good to use two descriptors - one for reading and other for writing, for readability and single write operation.

text_read = open('samiam.py', 'r').read()
words_replacer_dict = {" i " : " I ", "-i-" : "-I-"}
replaced_text = ""

for line in text_read.split("\n"):
    for word, new_word in words_replacer_dict.items():
        replaced_text += line.replace(word, new_word)

text_read.close()
text_write = open('samiam.py', 'w')
text_write.write(replaced_text)
text_write.close()

You can even keep a count and write based on count, if you are bothered about memory in this case. Just open the file in read mode with generator expression and keep a reference count to satisfy write operation. NOTE: Read here(not an official link), to learn better about dictionary methods.

However, if you prefer to use read and write, always use seek operation to get to the line that is to be replaced and use flush once you finish writing the file. However, you cannot replace the line that is already there in the file through the seek and flush method. You can merely add something to the file. (eg)

text = open('samiam.py', 'r+')
count = 1
new_text = ""
for line in text:
    new_text += "%d:%s\n" % (count, line)
    count += 1
text.seek(0)
text.truncate()
text.write(new_text)
text.seek(0)
for line in text:
    print line
text.close()

For a better reading on why it is not possible to read and write to file like you wish, please see here

Upvotes: 1

Prakash Kuma
Prakash Kuma

Reputation: 782

In your code just replace the line

for line in text:

with

for line in text.readlines():

Note that here I am assuming that the you are trying to add the output at the end of the file. Once you have read the entire file, the file pointer is at the end of the file (even if you opened the file in r+ mode). Thus doing a write will actually write to the end of the file, after the current contents.

You can examine the file pointer by embedding text.tell() at different lines.

Here is another approach:

with open("file","r") as file: 
    text=file.readlines() 
i=0 
while i < len(text): 
    if keyword in text[i]: 
        text[i]=text[i].replace(keywork,replacement) 
with open("file","w") as file: 
    file.writelines(text)

Upvotes: 2

gboffi
gboffi

Reputation: 25093

Use the fileinput module. (See also the MOTW site.)

import fileinput
keyword1 = " i "
keyword2 = "-i-"
replacement1 = " I "
replacement2 = "-I-"
for line in fileinput.input('your.file', inplace=True):
    line = line.rstrip()
    if keyword1 in line:
        line = line.replace(keyword1, replacement1)
    elif keyword2 in line:
        line = line.replace(keyword2, replacement2)
    print line

The fileinput module, when you use the inplace option, renames the input file and redirects stdout to a new file with the original file name

If you want to preserve the whitespace on the right of each line, don't rstrip and use print line, (note the final comma) to output the processed lines.

Upvotes: 1

Prashanth
Prashanth

Reputation: 1332

It is because you are trying to read and write at the same time. Try something like:

# Read operation
lines = []
for line in text.readlines():
    if keyword in line:
        lines.append(line.replace(keyword, replacement))
        print line
    elif keyword2 in line:
        lines.append(line.replace(keyword2, replacement2))
        print line
    else:
        lines.append(line)
        print line
text.close()

# Write operation
text = open('dummy.py', 'w+')
text.writelines(lines)
text.close()

Bonus:

with open('data.txt') as f:
     data = f.read()

is more pythonic.

Upvotes: 0

Related Questions