简体   繁体   中英

Replace a line in a text file with any new line using python

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM