2

I can go in to the file and read the line using enumerate but I can't figure out how to change the line.

The fileinput method overwrites the file and the append method in open() will only append to the end of the file.

I want to append and overwrite to only a certain line in the file while keeping the rest of the file intact.

with open('test2.py', 'r+') as f:
    for i, line in enumerate(f):
        if i == 4:
            if line != '2':
                line = '2'
                f.write(line)
            print line

I don't get any errors in the code above it just prints '2' in the terminal but it doesn't change the line of text in test2.py to '2'.

test2.py will be

#
#
#
'''
4
'''
#

I need to change 4 to 2

  • *I want to append and overwrite* -- I doubt anyone knows that that means. Post 3 lines of an example original file, and post an example of what you want the new file to look like. – 7stud Nov 21 '15 at 08:50
  • @7stud I've added an example, thanks for the input. –  Nov 21 '15 at 09:22
  • And why do you think that my answer fails to accomplish that for you? And that is still a terrible example because it is not clear why an enumerator is relevant. If you are looking for the text '4' on a line, then you just have to write: `if line.rstrip() == '4': print(whatever) else: print(line)` -- instead of `if fi.lineno() == 4:` – 7stud Nov 21 '15 at 09:31
  • I added another example to the bottom of my answer. – 7stud Nov 21 '15 at 09:46
  • @7stud How on earth is that a terrible example; it couldn't be more clearer. – booberz Nov 21 '15 at 13:32
  • @booberz, Then look at the accepted answer, and explain to me how that code has anything to do with that example. – 7stud Nov 21 '15 at 19:09
  • @7stud The accepted is the best answer. It uses enumerate for a start which is what he wanted. – booberz Nov 23 '15 at 22:38

5 Answers5

1

The "line = '2'" only means to change the variable in memory to '2'. The file content remains untouched. Then, you write the '2' to test2.py. It just appends '2' to test2.py.

I thought it would throw an error when writing to a file opened with "r+", but it didn't. It just appended.

Possible solution (though not so efficient):

lines = []
with open('test2.py', 'r+') as f:
   for i, line in enumerate(f):
      if i == 4:
         if line != '2':
            line = '2'
      lines.append(line)

with open('test2.py', 'w') as f:
   for line in lines:
      f.write(line)

Before:

12312312
123123123


1231231231

After:

12312312
123123123


2
jiegec
  • 116
  • 1
  • 6
  • Thankyou for the code and the explanation it answered the question how it was asked. –  Nov 21 '15 at 09:47
1

The fileinput method overwrites the file

Therefore:

1) For lines you don't want changed, write the original line.
2) For lines you want changed, write something else.

import fileinput as fi

with fi.input(
        files = 'data.txt', 
        inplace = True,
        backup = '.bak') as f:

    for line in f:
        if fi.lineno() == 4:
            print('hello')
        else:
            print(line, end='')

~/python_programs$ cat data.txt
line 1
line 2
line 3
line 4
line 5
line 6
~/python_programs$ p34 1.py
~/python_programs$ cat data.txt
line 1
line 2
line 3
hello
line 5
line 6

Or maybe you want to do this:

~/python_programs$ cat data.txt
line 1
line 2
line 3
line 4
line 5
line 6
~/python_programs$ p34 1.py 
~/python_programs$ cat data.txt
line 1
line 2
line 3
line 4
extra line
line 5
line 6

import fileinput as fi

with fi.input(
        files = 'data.txt', 
        inplace = True,
        backup = '.bak') as f:

    for line in f:
        if fi.lineno() == 4:
            print(line, end='')
            print('extra line')
        else:
            print(line, end='')

Edit:

~/python_programs$ cat data.txt
#
#
#
'''
4
'''
#
~/python_programs$ p 1.py 
~/python_programs$ cat data.txt
#
#
#
'''
2
'''
#

import fileinput as fi

f = fi.input(
        files = 'data.txt', 
        inplace = True,
        backup = '.bak'
) 

for line in f:
    newline_removed = line.rstrip()

    if newline_removed == '4':
        print '2'
    else:
        print(newline_removed) #print() adds a newline to end of text

f.close()
7stud
  • 46,922
  • 14
  • 101
  • 127
0

First, you open it in read (r+) mode. Use write(w+) instead. Second(and more important) here you overrides file contents with 2.

So I'd do:

with open('test2.py', 'w') as f:
    lines = f.readlines()
    if lines[4] != '2':
        lines[4] = 2
    f.writelines(lines)
Andrii Rusanov
  • 4,405
  • 2
  • 34
  • 54
0

You can't change a line directly in a file. You should open file for reading , read all lines, make all the changes. close the file and re-open it for writing than write your changed data.

with open('test2.py', 'r') as f:
    mylines = f.readlines()

## changes here

with open('test2.py', 'w') as f:
    f.write(newdata)
Assem
  • 11,574
  • 5
  • 59
  • 97
0

I'd suggest use file.readlines(), file.writelines and slice like this:

>>> with open('file') as f:
...     a = f.readlines()

>>> a
['1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n']

>>> if a[4] != '2'+'\n':
...     a[4] = '2'+'\n'

>>> a
['1\n', '2\n', '3\n', '4\n', '2\n', '6\n', '7\n', '8\n', '9\n']

>>> with open('file', 'w') as f:
...         f.writelines(i)
Remi Guan
  • 21,506
  • 17
  • 64
  • 87