Lets say I have one text file as details.txt
details.txt
id=0=pending
id=1=pending
id=abc2=pending
id=x2=found
#cursor always points to the new line since I am appending \n in the end of each line
Now I have one python file say update.py , what i'm trying to do is replace the line having a particular id which is having pending (for ex: id=1=pending) with (id=1=missing) or (id=1=found).
PS. NOTE that we are only changing pending to either missing or found, rest id=1= is same. for example, if we replace id=1=pending in details.txt with id=1=found , it should look like this:
id=0=pending
id=1=found
id=abc2=pending
id=x2=found
#cursor always points to the new line since I am appending \n in the end of each line
Here is what I have written
update.py
f = open("details.txt","r+")
temp = f.readlines()
for line in temp:
word = line.split('=')#using = as a delimiter
if word[1]=="1" and word[2]=="pending\n": #pending\n because while writing, we are appending \n to each line
striped = line.strip()
new_line = striped.replace("pending","found")
new_content = new_line #id=1=found
pos = f.tell() #it will give the current position
if pos-len(line)-1>=0: #checking whether we have any line or not
pos = pos-len(line)-1 #going to the start of a line and -1 to remove \n
f.seek(pos) #setting the pointer to the start of the line we want to replace , (start of 2nd line in this case)
f.write(new_content) #writing the content
f.close()
output which i am getting
id=0=pending
id=1=foundng
id=abc2=pending
id=x2=found
#cursor always points to the new line since I am appending \n in the end of each line
so instead of ( id=1=found ) we are getting ( id=1=foundng ), since len(found) is 5 and len(pending) is 7, so extra 2 chars at the end of pending ie ng is not replaced.
Please tell me how should i do this.
Also please tell me, if i want to remove a particular line, then how can i do it.
for ex:
if i want to remove line ( id=abc2=pending ), how should i do it.
The output should be like this:
id=0=pending
id=1=pending
id=x2=found
#cursor always points to the new line since I am appending \n in the end of each line
Please note that the line is removed along with \n
Any Help will be appreciated
Instead of using if statement, using regular expression will help you,
Since you are looking for a specific id followed by the word 'pending'
, a simple regex: "id=your_id=pending"
will work.
Then you can use re.sub
to replace the entire line by what you want. Here id=your_id=missing/found"
Note: this answer is probably not the best one, since you re-write most of the lines, but for small files, works perfectly.
import re
FILENAME = "textfile.txt"
def update_file(filename,id,word_to_add,lines_to_remove):
lines_to_remove = [s + "\n" for s in lines_to_remove]
#adding \n to all lines you want to remove
pattern =re.compile("^id="+str(id)+"=pending")
new_lines=[]
with open(FILENAME,'r+') as file:
for line in file:
if line not in lines_to_remove: # keeping only lines desired
new_lines.append(pattern.sub("id=1="+word_to_add,line))
with open(FILENAME,'w') as file:
file.writelines(new_lines)
return 0
update_file(FILENAME,1,"missing",["id=abc2=pending"])
#Output
#id=0=pending
#id=1=missing
if you print new_content
instead of f.write(new-content)
. It can be seen that the problem is not actually in the replace function and the word gets replaced as it should
# f.write(new_content)
print(new_content)
Output: id=1=found
as it should be
The problem is that when you overwrite on the pre-existing file, it replaces the characters that were already there in the file, and in this case, it so happens that the last two letters of "pending" dont need to be overwritten.
To solve this you have to rewrite the whole file:
f = open("details.txt","r")
temp = f.readlines()
output_text = []
for line in temp:
word = line.split('=')
if word[1]=="1" and word[2]=="pending\n":
line = line.replace("pending\n", "found\n") # replace pending with found
output_text.append(line)
f.close()
f = open("details.txt", "w")
f.write("".join(output_text))
f.close()
Now the file is:
id=0=pending
id=1=found
id=abc2=pending
id=x2=found
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.