osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

how to replace line on particular line in file[no need to write it back whole file again]


On 2018-10-11 11:44, Iranna Mathapati wrote:
> Hi Team,
> 
> How to replace particular line text with  new text on a file
> i have below code but its writing whole code.
> 
> def replace_line(file_name, line_num, text):
>     lines = open(file_name, 'r').readlines()
>     lines[line_num] = text
>     out = open(file_name, 'w')
>     out.writelines(lines)  <<<<< *writing back whole file instead of
> particular line*
>     out.close()
> replace_line('stats.txt', 0, 'good')
> 
> 
> Thanks,
> Iranna M
> 

Can't be done.

There's no easy way to write to the middle of a file (though I think it
can be done by mmap'ing a file) -- and even if you manage to do that,
you'd have to write back anything after the changed line if the length
of that line changed by as little as a byte.

If you really want, you can avoid writing back anything *before* your
change by carefully using truncate():

def replace_line(file_name, line_num, new_text):
    # Use a with statement to make sure the file is closed
    with open(file_name, 'r+') as f:
        # Ignore the first (line_num) lines
        for _ in range(line_num):
            f.readline()

        # Save position, skip the line to be replaced
        line_start = f.tell()
        f.readline()

        # We're keeping the rest of the file:
        remaining_content = f.read()

        # Chop off the file's tail!
        f.seek(line_start)
        f.truncate()

        # Write the new tail.
        if not new_text.endswith('\n'):
            new_text = new_text + '\n'
        f.write(new_text)
        f.write(remaining_content)


That works, but your solution is more elegant.* This solution might make
sense for fairly large files where you can guarantee that the change
will be near the end.

* though you should close the file after you read it, preferable using a
with statement.