Read and Overwrite a File in Python

Read and overwrite a file in Python

If you don't want to close and reopen the file, to avoid race conditions, you could truncate it:

f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()

The functionality will likely also be cleaner and safer using open as a context manager, which will close the file handler, even if an error occurs!

with open(filename, 'r+') as f:
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()

Replace and overwrite instead of appending

You need seek to the beginning of the file before writing and then use file.truncate() if you want to do inplace replace:

import re

myfile = "path/test.xml"

with open(myfile, "r+") as f:
data = f.read()
f.seek(0)
f.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>", r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", data))
f.truncate()

The other way is to read the file then open it again with open(myfile, 'w'):

with open(myfile, "r") as f:
data = f.read()

with open(myfile, "w") as f:
f.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>", r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", data))

Neither truncate nor open(..., 'w') will change the inode number of the file (I tested twice, once with Ubuntu 12.04 NFS and once with ext4).

By the way, this is not really related to Python. The interpreter calls the corresponding low level API. The method truncate() works the same in the C programming language: See http://man7.org/linux/man-pages/man2/truncate.2.html

Reading a file and then overwriting it in Python

Truncate the file after seeking to the front. That will remove all of the existing data.

>>> open('deleteme', 'w').write('Read and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in Pythonaa')
>>> f = open('deleteme', 'r+')
>>> f.read()
'Read and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in PythonRead and Overwrite a File in Pythonaa'
>>> f.seek(0)
>>> f.truncate()
>>> f.write('bbb')
>>> f.close()
>>> open('deleteme').read()
'bbb'
>>>

Trying to read into a file and then overwrite the file, replacing old data with new data

If you want to re write the all file you need to open it with 'r' first, then close it with .close() then re open the file with 'w' to write on the file.
When you write on a file who isn't empty, you erase all it content.

Python process and overwrite external text file

You need to open temp file and read from file, remove old file and rename to new name

import os
import numpy as np
import math
import cv2 as cv

#path = '/media/D/code/OCR/text-detection-ctpn/data/mlt_english+chinese/image'
gt_file = '12.txt'
output = open("temp.txt","w")
with open(gt_file, 'r') as f:
for line in f:
line = line.replace("[", "")
line = line.replace("(", "")
line = line.replace(")", "")
line = line.replace("]", "")
line = line.replace(" ", "")

output.write(line)
output.close()
os.remove(gt_file) # remove old file
os.rename("temp.txt",gt_file) # rename as old file

overwriting a specific line in a txt file

Your first approach was already near the solution, but there you are not selecting the 1st or 3rd line, you are just creating a list containing a 1 (lines = [1]. You first need to open the file. Then, you can use file.readlines which returns a list containing each line as one separate string, instead of file.read, which returns the whole file as one string. Then, you assign a new value to one specific line, open the same file again, but now in write mode, use file.writelines to write the list of lines back to the file, and that's it !

if answer == "R":
print("Racer")
with open("character.txt", "r") as f: # with automatically closes the file - no need to do so yourself
lines = f.readlines()

amount = input("please enter the amount") # no need to convert the amount to int first if you then convert it back to string below
lines[0] = answer + "-" + amount
with open("character.txt", "w") as f:
f.writelines(lines)

I will let you adapt the code for the other answers yourself. Please note that you could save many lines of code if you would put the above in a function hat accepts a number (the line you want to overwrite) and a string (the answer).

You surely wondered why I put lines[0] = ... in the code. Well, we start counting from 1, but Python starts counting from 0 ! What you call the 1st line, is for Python the 0st, what you call the 2nd, is for Python the 1st. and so on.

And here some notes to your second approach: file.seek seeks to the byte in the file specified by the number you passed to it, not to the line. And file.truncate resizes the file. It does not overwrite the file.

Overwrite text file but not from The start

One solution is to just read the first two lines and write them again. Then write the new lines after that.

How to read items in a text file and overwrite it based on the user's inputs

When updating files, the more secure way to go is to create a temporal file where you write the content, while you keep the original safe and untouched. Then, when the writing process is done, you can remove the original and rename the temporal file.

Also, I think you should have some sort of unique ID that identifies each task. I had to use the row number to identify them, but it would be better if you include some immutable ID.

Finally, I suggest you to use a dictionary instead of a list when fetching the tasks. It allows you to access and update the fields more easily.

(In the example below, I didn't include all the menu options, I only included the username edit to illustrate how it should work)

import os
from pprint import pprint

# The view_mine function should receive the username as a parameter
def view_mine(username):
tasks = []
i = 0
with open('tasks.txt') as f:
lines = f.read().splitlines()
for db_row, line in enumerate(lines):
assigned_to, *rest = line.split(', ')
if username == assigned_to:
# use a dictionary to easily refer to the taks' fields
data = {k: v for k, v in zip(
('number', 'db_row', 'assigned_to', 'title', 'description',
'due_date', 'date_assigned', 'completed'),
(i + 1, db_row, assigned_to, *rest))}
tasks.append(data)
i += 1
# You can customize what you want to print, I just used pprint as a shortcut for this example
pprint(tasks)
task_num = int(input("Please select Task Number you would like to edit: "))
# Get specific task at given index
task = tasks[task_num - 1]
edit_option = input('''Would you like to:
e - edit task
c - mark complete
-1- return to main menu\n''')
if edit_option == 'e':
# This is how you would refer to the fields
if task['completed'] == 'No':
edit = input('''What would you like to edit:
u - username
d - due date\n''')
if edit == "u":
# updating a field
task['assigned_to'] = input("Please input new user: ")

# Actual file update part
fetched_rows = [task['db_row'] for task in tasks]
with open('tasks.txt') as f, open('temp.txt', 'w') as t:
for db_row, line in enumerate(f):
if db_row in fetched_rows:
fetched_rows.remove(db_row)
print(', '.join(v for k, v in list(tasks.pop(0).items())[2:]), file=t)
else:
print(line.strip(), file=t)

os.remove('tasks.txt')
os.rename('temp.txt', 'tasks.txt')

PYTHON - Read and overwrite file and add each value by one

Your file is not open for writing, this line

infile = open(file,'r')

means that open the file for reading.
If you want to open the file for writing, you can use 'w' (write) or 'r+' (read and write) use this instead:

infile = open(file,'r+')

for more you can read (http://www.pythonforbeginners.com/files/reading-and-writing-files-in-python) --> Mode Section.

If you use 'r+' the code should be something like

infile = open(file, 'r+')
for line in infile:
val = int(line)
infile.write(str(val + 1) + '\n')
infile.truncate()
infile.close()

But I suppose this wont serve the purpose which you want to do, this will just append the values to the end. If you want to write these new values to file, use this instead:

infile = open(file, 'r')
lines = infile.readlines() #this gives a list of all lines
infile.close()
outfile = open(file, 'w') #erases previous contents
for line in lines:
outfile.write(str(int(line) + 1) + '\n') #if you are sure file have int's only
outfile.close()


Related Topics



Leave a reply



Submit