9

I have a file that I open and i want to search through till I find a specific text phrase at the beginning of a line. I then want to overwrite that line with 'sentence'

sentence = "new text"           "
with open(main_path,'rw') as file: # Use file to refer to the file object
    for line in file.readlines():
        if line.startswith('text to replace'):
            file.write(sentence)

I'm getting:

Traceback (most recent call last):
 File "setup_main.py", line 37, in <module>
with open(main_path,'rw') as file: # Use file to refer to the file object
ValueError: must have exactly one of create/read/write/append mode

How can I get this working?

user1592380
  • 30,233
  • 76
  • 247
  • 468
  • 1
    Possible duplicate of [python open built-in function: difference between modes a, a+, w, w+, and r+?](https://stackoverflow.com/questions/1466000/python-open-built-in-function-difference-between-modes-a-a-w-w-and-r) – mercator Dec 24 '18 at 21:15

3 Answers3

13

You can open a file for simultaneous reading and writing but it won't work the way you expect:

with open('file.txt', 'w') as f:
    f.write('abcd')

with open('file.txt', 'r+') as f:  # The mode is r+ instead of r
    print(f.read())  # prints "abcd"

    f.seek(0)        # Go back to the beginning of the file
    f.write('xyz')

    f.seek(0)
    print(f.read())  # prints "xyzd", not "xyzabcd"!

You can overwrite bytes or extend a file but you cannot insert or delete bytes without rewriting everything past your current position. Since lines aren't all the same length, it's easiest to do it in two seperate steps:

lines = []

# Parse the file into lines
with open('file.txt', 'r') as f:
    for line in f:
        if line.startswith('text to replace'):
            line = 'new text\n'

        lines.append(line)

# Write them back to the file
with open('file.txt', 'w') as f:
    f.writelines(lines)

    # Or: f.write(''.join(lines))
Blender
  • 275,078
  • 51
  • 420
  • 480
1

You can't read and write to the same file. You'd have to read from main_path, and write to another one, e.g.

sentence = "new text"
with open(main_path,'rt') as file: # Use file to refer to the file object
    with open('out.txt','wt') as outfile:
        for line in file.readlines():
            if line.startswith('text to replace'):
                outfile.write(sentence)
            else:
                outfile.write(line)
zyxue
  • 6,998
  • 3
  • 33
  • 62
0

Not the problem with the example code, but wanted to share as this is where I wound up when searching for the error.

I was getting this error due to the chosen file name (con.txt for example) when appending to a file on Windows. Changing the extension to other possibilities resulted in the same error, but changing the file name solved the problem. Turns out the file name choice caused a redirect to the console, which resulted in the error (must have exactly one of read or write mode): Why does naming a file 'con.txt' in windows make Python write to console, not file?