reading file only once throughout the other functions - python

with open('sample.txt', 'r') as f:
def function1():
file = f.readlines()
...code that will read the file and modify
def function2():
file = f.readlines()
...code that will read the file and modify
with open('output.txt', 'w') as outputFile:
for file in file:
function1()
function2()
Here is my code. I am trying to read the file only once. I have functions that will read different parts from the file and write it as in output.txt file.
I tried but it is giving me an error "ValueError: I/O operation on closed file."
helpp

If you're reading all of the file in each function, you're better off doing something like the following:
with open('sample.txt','r') as f:
file = f.readlines()
function1(file) # so don't readline multiple times
function2(file) # in your function just operate on data
with open('output.txt', 'w') as f:
f.writelines(file)

Firstly, some notes:
The for file in file piece means "For each line in the file I will do the following".
Your 2 functions are not indented (I think) so that could cause an issue also.
f.readlines() takes the whole file and stores it as the variable named file.
The best approach to this would be to read the file 1 time with file = f.readlines(). Now that file has all the lines, loop over those lines while making any changes that you need to make. For each line, save that line to a new file (look up how append works).
Right now you aren't printing anything out which makes debugging very hard when you are new, so start with this:
def my_change_text_function(line):
#here you can write code that will have the 1 line available to change.
changed_line = ......
return changed_line
f = open("pok.txt")
newfile = open("newfile.txt", "a")
file = f.readlines()
for line in file:
print(line)
changed_line = my_change_text_function(line)
#Do your changes to the line here, character replacement, etc.
newfile.write(changed_line)
Now you will have a new file named newfile.txt that contains your changes. This is all of the code required, minus the code you need to modify the line.

Related

How to create a new file and copy content of existing file into newly created file python

I have a python function here that takes in 2 params, old_file is the name of the file that contains the content that I want to copy over to the new file and the new_file is the name for the file I want to create. Right now my code looks like this and it would throw an error which is a type error that says "TypeError: expected str, bytes or os.PathLike object, not TextIOWrapper". Is there a more efficient way to do it?. In addition when I point at with open(file, "r+") as f2: I get this warning
Note. this works if the file is already pre-made but not when i make it in the function
def copy_In(old_file, new_file):
file = open(new_file, "w")
with open(file, "r+") as f2:
for x in range(10):
f2.readline()
pos = f2.tell()
f2_remainder = f2.read()
f2.seek(pos)
with open(old_file, "r") as f1:
for line in f1:
f2.write(line)
f2.write(f2_remainder)
just do it like:
def copy_file(old_fname, new_fname):
with open(old_fname, "rt") as old_fobj, open(new_fname, "wt") as new_fobj:
new_fobj.write(old_fobj.read())
we are opening first file in read mode and second in write mode and reading the entire content of first file and writing it in second file.

how to rename a file and keep the original

I would like to keep unaltered the template.txt file after I insert some text into it and save the altered text file with a new name. Currently, my code overwrites the template.txt.
f = open("template.txt", "r")
contents = f.readlines()
f.close()
#insert the new text at line = 2
contents.insert(2, "This is a custom inserted line \n")
#open the file again and write the contents
f = open("template.txt", "w")
contents = "".join(contents)
f.write(contents)
f.close()
os.rename('template.txt', 'new_file.txt')
As people have mentioned, you're going to want to copy the contents of template.txt into a new file and then edit this new file. This allows you to keep the original file unmodified and you don't have to worry about renaming files at the end. Another tip: the with open(file) as f syntax keeps you from having to remember to close files when you're editing them and is the recommended way of working with files in python
with open("template.txt") as f:
lines = f.readlines()
with open("new_file.txt", "w+") as n:
lines.insert(2, "This is a custom inserted line \n")
n.writelines(lines)

string.replace method in python

I am a newbie with python, so kindly excuse for asking basic question.
I am trying to use the string.replace method in python and getting a weird behavior. here is what I am doing:
# passing through command line a file name
with open(sys.argv[2], 'r+') as source:
content = source.readlines()
for line in content:
line = line.replace(placeholerPattern1Replace,placeholerPattern1)
#if I am printing the line here, I am getting the correct value
source.write(line.replace(placeholerPattern1Replace,placeholerPattern1))
try:
target = open('baf_boot_flash_range_test_'+subStr +'.gpj', 'w')
for line in content:
if placeholerPattern3 in line:
print line
target.write(line.replace(placeholerPattern1, <variable>))
target.close()
When I am checking the values in the new file, then these are not replaced. I could see that the value of the source is also not changed, but the content had changed, what am I doing wrong here?
Rather do something like this -
contentList = []
with open('somefile.txt', 'r') as source:
for line in source:
contentList.append(line)
with open('somefile.txt','w') as w:
for line in contentList:
line = line.replace(stringToReplace,stringToReplaceWith)
w.write(line)
Because with will close your file after runing all the statements wrapped within it, which means the content local variable will be nil in the second loop.
You are reading from the file source and also writing to it. Don't do that. Instead, you should write to a NamedTemporaryFile and then rename it over the original file after you finish writing and close it.
Try this:
# Read the file into memory
with open(sys.argv[2], 'r') as source:
content = source.readlines()
# Fix each line
new_content = list()
for line in content:
new_content.append(line.replace(placeholerPattern1Replace, placeholerPattern1))
# Write the data to a temporary file name
with open(sys.argv[2] + '.tmp', 'w') as dest:
for line in new_content:
dest.write(line)
# Rename the temporary file to the input file name
os.rename(sys.argv[2] + '.tmp', sys.argv[2])

Use process substitution as input file to Python twice

Consider the following python script
#test.py
import sys
inputfile=sys.argv[1]
with open(inputfile,'r') as f:
for line in f.readlines():
print line
with open(inputfile,'r') as f:
for line in f.readlines():
print line
Now I want to run test.py on a substituted process, e.g.,
python test.py <( cat file | head -10)
It seems the second f.readlines returns empty. Why is that and is there a way to do it without having to specify two input files?
Why is that.
Process substitution works by creating a named pipe. So all the data consumed at the first open/read loop.
Is there a way to do it without having to specify two input files.
How about buffering the data before using it.
Here is a sample code
import sys
import StringIO
inputfile=sys.argv[1]
buffer = StringIO.StringIO()
# buffering
with open(inputfile, 'r') as f:
buffer.write(f.read())
# use it
buffer.seek(0)
for line in buffer:
print line
# use it again
buffer.seek(0)
for line in buffer:
print line
readlines() will read all available lines from the input at once. This is why the second call returns nothing because there is nothing left to read. You can assign the result of readlines() to a local variable and use it as many times as you want:
import sys
inputfile=sys.argv[1]
with open(inputfile,'r') as f:
lines = f.readlines()
for line in lines:
print line
#use it again
for line in lines:
print line

Python newbie: trying to create a script that opens a file and replaces words

im trying to create a script that opens a file and replace every 'hola' with 'hello'.
f=open("kk.txt","w")
for line in f:
if "hola" in line:
line=line.replace('hola','hello')
f.close()
But im getting this error:
Traceback (most recent call last):
File "prueba.py", line 3, in
for line in f: IOError: [Errno 9] Bad file descriptor
Any idea?
Javi
open('test.txt', 'w').write(open('test.txt', 'r').read().replace('hola', 'hello'))
Or if you want to properly close the file:
with open('test.txt', 'r') as src:
src_text = src.read()
with open('test.txt', 'w') as dst:
dst.write(src_text.replace('hola', 'hello'))
Your main issue is that you're opening the file for writing first. When you open a file for writing, the contents of the file are deleted, which makes it quite difficult to do replacements! If you want to replace words in the file, you have a three-step process:
Read the file into a string
Make replacements in that string
Write that string to the file
In code:
# open for reading first since we need to get the text out
f = open('kk.txt','r')
# step 1
data = f.read()
# step 2
data = data.replace("hola", "hello")
f.close()
# *now* open for writing
f = open('kk.txt', 'w')
# step 3
f.write(data)
f.close()
You've opened the file for writing, but you're reading from it. Open the original file for reading and a new file for writing. After the replacement, rename the original out and the new one in.
You could also have a look at the with statement.

Categories

Resources