There is a combination of techniques which I found useful in solving this issue:
with open(file, 'r+') as fd: contents = fd.readlines() contents.insert(index, new_string) # new_string should end in a newline fd.seek(0) # readlines consumes the iterator, so we need to start over fd.writelines(contents) # No need to truncate as we are increasing filesize
In our particular application, we wanted to add it after a certain string:
with open(file, 'r+') as fd: contents = fd.readlines() if match_string in contents[-1]: # Handle last line to prevent IndexError contents.append(insert_string) else: for index, line in enumerate(contents): if match_string in line and insert_string not in contents[index + 1]: contents.insert(index + 1, insert_string) break fd.seek(0) fd.writelines(contents)
If you want it to insert the string after every instance of the match, instead of just the first, remove the else: (and properly unindent) and the break.
Note also that the and insert_string not in contents[index + 1]: prevents it from adding more than one copy after the match_string, so it's safe to run repeatedly.