1

I have a text file of the format below, and I am trying to edit/update text in the file.

VAR_GROUP
Var1 : DATATYPE1;(Description Var1)
Var2 : DATATYPE2;(Text to be added here)
Var3 : DATATYPE3;(Description Var3)
Var4 : DATATYPE4;(Text to be added here)
END_GROUP

Using Python I am trying to add certain description of for eg., Var3 and Var4. With code I wrote the logic is working fine but the text is added to the end of the file and not at the required position.

def search_write_in_file(file_name, string_to_search, description):
with open(file_name, 'r+') as file_obj:
    # Read all lines in the file
    for line in file_obj:
        # For each line, check if line contains the string
        line_number += 1
        if (string_to_search in line) and flag_found == 0:
            line = line[:-1]+description+'\n'
            file_obj.write(line)
            flag_found =1

read_obj.close()

Current Output
VAR_GROUP
Var1 : DATATYPE1;(Description Var)
Var2 : DATATYPE2;
Var3 : DATATYPE3;(Description Var3)
Var4 : DATATYPE4;
END_GROUP
Var1 : DATATYPE1;(Description Var1)
Var2 : DATATYPE2;(Description Var2)
Var3 : DATATYPE3;(Description Var3)
Var4 : DATATYPE4;(Description Var4)

What could be the possible reason that the the mentioned specific location is not edited, rather added at the end. Thanks in advance.

abhi0687
  • 13
  • 3
  • Does this answer your question? [How to modify a text file?](https://stackoverflow.com/questions/125703/how-to-modify-a-text-file) – Tzane Oct 14 '21 at 13:19
  • Thanks for the suggestion. I looked into the mentioned solution before posting my question. Does that mean there is no possibility to edit a file without copying the file contents into a new file ? – abhi0687 Oct 14 '21 at 14:05
  • Yes, you have to do the read/write cycle to modify some part of the file. If you want to avoid copying, you can overwrite the old file with your modified file. – Tzane Oct 15 '21 at 07:13

3 Answers3

1

Use the python seek() function. Using this you can change the cursor position in the file character by character. Also, change the mode to a+ in your function as in r+ mode you can only read the file. In w+ mode, the file would be overwritten.

Read more about it in this website: https://www.w3schools.com/python/ref_file_seek.asp

0

You have opened the file in r+ mode. Writing to a file needs w+ or a+ mode. Try this:

def search_write_in_file(file_name, string_to_search, description):
 lines=[]
 with open(file_name, 'r+') as file_obj:
     # Read all lines in the file
     lines = file_obj.readlines()
 # Make the changes
 for idx in range(len(lines)):
     line = lines[idx]
     # For each line, check if line contains the string
     if (string_to_search in line) and flag_found == 0:
         line = line[:-1]+description+'\n'
         lines[idx]=line
         flag_found =1
 # w+ mode truncates the content and then writes the content back again
 with open(file_name, 'w+') as file_obj:
    file_obj.writelines(line)

Alternatively, you can use the seek() method as mentioned in the other answer to get exactly one line at a time, edit it and write it back. You still need to be cautious of the mode though.

srdg
  • 585
  • 1
  • 4
  • 15
0

I'd use regular expressions to match and replace text inside your file

import re

def search_write_in_file(file_name, string_to_search, description):
    with open(file_name, 'r+') as file_obj:
        text = file_obj.read()
    new_text = re.sub(string_to_search,r"\1 {0}\n".format(description),text)
    with open(file_name, 'w') as file_obj:
        file_obj.write(new_text)
    print(new_text)

if __name__ == '__main__':
    search_write_in_file('text_to_edit.txt',r'(DATATYPE2;\n)',"test2")
    search_write_in_file('text_to_edit.txt',r'(DATATYPE4;\n)',"test4")

This will update the existing file to be

VAR_GROUP
Var1 : DATATYPE1;(Description Var)
Var2 : DATATYPE2; test2
Var3 : DATATYPE3;(Description Var3)
Var4 : DATATYPE4; test4
END_GROUP
scotty3785
  • 6,763
  • 1
  • 25
  • 35
  • Thanks @scotty3785. This is what I was expecting and it works without rewriting the whole file. But if I wish to iteratively call the function "search_write_in_file" then I need to pass the regex as a variable, and not like r'(DATATYPE2;\n). How can this be achieved ? – abhi0687 Nov 28 '21 at 21:27
  • @abhi0687 The function I wrote already supports the regex being passed as a variable. Rather than using the regex directly in the function call, pass it in as a seperate variable. `my_regex = r'(DATATYPE2:\n)'` then `search_write_in_file('text_to_edit.txt', my_regex, 'test2')` – scotty3785 Nov 29 '21 at 08:47