def createOutfile(text,lines,outfile):
infile = open(text, 'r')
newtext = open(outfile, 'w')
count = 0
newfile = ''
for line in infile:
count = count + 1
newfile = newfile + "{0}: {1}".format(count,line)
newtext.write(newfile)
print(newtext)
I'm trying to take a file (text) and create a copy of that file (outfile) that just numbers the lines. The code i have now doesn't print an error but it gives me this:
<_io.TextIOWrapper name='mydata.out' mode='w' encoding='UTF-8'>
If i replace print(newtext) with print(newfile) it gives me exactly what i want. What am i doing wrong?
To read a file's content you need to use its .read() method:
newtext.seek(0) #Move the file pointer to the start of the file.
print(newtext.read())
You can open the output file in read-write mode,
def number_lines(old_file_name, new_file_name, fmt="{}: {}"):
with open(old_file_name) as inf, open(new_file_name, "w+") as outf:
for i,line in enumerate(inf, 1):
outf.write(fmt.format(i, line))
# show contents of output file
outf.seek(0) # return to start of file
print(outf.read())
or just print each line as it is written:
def number_lines(old_file_name, new_file_name, fmt="{}: {}"):
with open(old_file_name) as inf, open(new_file_name, "w+") as outf:
for i,line in enumerate(inf, 1):
numbered = fmt.format(i, line)
outf.write(numbered)
print(numbered.rstrip())
What you are doing is:
line 3: newtext contains the file descriptor of your output file.
line 5-8: newfile contains the text you want to output.
line 10: you print your file descriptor (newtext) and the outputed text (newfile).
At line 10, when you print the file descriptor (newtext), python displays the representation of this file descriptor:
the class name: TextIOWrapper
the name of you file: mydata.out
the opening mode: w
and the encoding: UTF-8
And when you print newfile, it displays the string you created just before.
If you want to read your file after writing in it, you need to open it in read/write mode: "w+":
>>> f = open("File", "w+") # open in read/write mode
>>> f.write("test") # write some stuff
>>> # the virtual cursor is after the fourth character.
>>> f.seek(0) # move the virtual cursor in the begining of the file
>>> f.read(4) # read the data you previously wrote.
'test'
Related
I want to append some text to every line in my file
Here is my code
filepath = 'hole.txt'
with open(filepath) as fp:
line = fp.readline()
cnt = 1
while line:
#..........
#want to append text "#" in every line by reading line by line
text from .txt file
line = fp.readline()
cnt += 1
You can read the lines and put them in a list. Then you open the same file with write mode and write each line with the string you want to append.
filepath = "hole.txt"
with open(filepath) as fp:
lines = fp.read().splitlines()
with open(filepath, "w") as fp:
for line in lines:
print(line + "#", file=fp)
Assuming you can load the full text in memory, you could open the file, split by row and for each row append the '#'. Then save :-) :
with open(filepath, 'r') as f: # load file
lines = f.read().splitlines() # read lines
with open('new_file.txt', 'w') as f:
f.write('\n'.join([line + '#' for line in lines])) # write lines with '#' appended
I'll assume the file is small enough to keep two copies of it in memory:
filepath = 'hole.txt'
with open(filepath, 'r') as f:
original_lines = f.readlines()
new_lines = [line.strip() + "#\n" for line in original_lines]
with open(filepath, 'w') as f:
f.writelines(new_lines)
First, we open the file and read all lines into a list. Then, a new list is generated by strip()ing the line terminators from each line, adding some additional text and a new line terminator after it.
Then, the last line overwrites the file with the new, modified lines.
does this help?
inputFile = "path-to-input-file/a.txt"
outputFile = "path-to-output-file/b.txt"
stringToAPpend = "#"
with open(inputFile, 'r') as inFile, open(outputFile, 'w') as outFile:
for line in inFile:
outFile.write(stringToAPpend+line)
I have a file txt, where there are severals lines... Some of these are links. My question is: How can I catch all this links and save them on another txt file? I'm a newbie.
I tried with this but it doesn't work:
filee = open("myfile.txt").readlines()
out_file = open("out.txt","w")
out_file.write("")
out_file.close()
for x in filee:
if x.startswith("http"):
out_file.write(x)
print (x)
You can't write to a closed file. Just move the out_file.close() at the end of your code:
filee = open("myfile.txt").readlines()
out_file = open("out.txt","w")
out_file.write("")
for x in filee:
if x.startswith("http"):
out_file.write(x)
print (x)
out_file.close()
Here a cleaner version:
# open the input file (with auto close)
with open("myfile.txt") as input_file:
# open the output file (with auto close)
with open("out.txt", "w") as output_file:
# for each line of the file
for line in input_file:
# append the line to the output file if start with "http"
if line.startswith("http"):
output_file.write(line)
You can also combine the two with:
# open the input/output files (with auto close)
with open("myfile.txt") as input_file, open("out.txt", "w") as output_file:
# for each line of the file
for line in input_file:
# append the line to the output file if start with "http"
if line.startswith("http"):
output_file.write(line)
I'm trying to make a code to rewrite a specific line from a .txt file.
I can get to write in the line i want, but i can't erase the previous text on the line.
Here is my code:
(i'm trying a couple of things)
def writeline(file,n_line, text):
f=open(file,'r+')
count=0
for line in f:
count=count+1
if count==n_line :
f.write(line.replace(str(line),text))
#f.write('\r'+text)
You can use this code to make a test file for testing:
with open('writetest.txt','w') as f:
f.write('1 \n2 \n3 \n4 \n5')
writeline('writetest.txt',4,'This is the fourth line')
Edit: For Some reason, if i use 'if count==5:' the code compiles ok (even if it doen't erase the previous text), but if i do 'if count==n_line: ', the file ends up with a lot of garbage.
The Answers work, but i would like to know what are the problems with my code, and why i can't read and write. Thanks!
You are reading from the file 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.
Or if the size of the file is guaranteed to be small, you can use readlines() to read all of it, then close the file, modify the line you want, and write it back out:
def editline(file,n_line,text):
with open(file) as infile:
lines = infile.readlines()
lines[n_line] = text+' \n'
with open(file, 'w') as outfile:
outfile.writelines(lines)
Use temporary file:
import os
import shutil
def writeline(filename, n_line, text):
tmp_filename = filename + ".tmp"
count = 0
with open(tmp_filename, 'wt') as tmp:
with open(filename, 'rt') as src:
for line in src:
count += 1
if count == n_line:
line = line.replace(str(line), text + '\n')
tmp.write(line)
shutil.copy(tmp_filename, filename)
os.remove(tmp_filename)
def create_test(fname):
with open(fname,'w') as f:
f.write('1 \n2 \n3 \n4 \n5')
if __name__ == "__main__":
create_test('writetest.txt')
writeline('writetest.txt', 4, 'This is the fourth line')
For opening and reading 1 file even after adding the close argument it is giving the error. The code written is as below:
infilename = "Rate.txt"
infile = open(infilename, "r").readlines()
firstLine = infile.pop(0) #removes the header(first line)
infile = infile[:-1]#removes the last line
for line in infile:
a = line.split()
CheckNumeric = a[4]
CheckNumeric1 = a[5]
strfield = a[3]
infile.close()
By doing infile = open(infilename, "r").readlines() you have actually assigned infile to be a list, rather than an open file object. The garbage collecter should sweep up your open file and close it for you, but a better way to handle this would be to use a with block:
infilename = "Rate.txt"
with open(infilename, "r") as infile:
line_list = infile.readlines()
firstLine = line_list.pop(0) #removes the header(first line)
line_list = line_list[:-1]#removes the last line
for line in line_list:
a = line.split()
CheckNumeric = a[4]
CheckNumeric1 = a[5]
strfield = a[3]
In the code above, everything that is indented within the with block will execute while the file is open. Once the block ends the file is automatically closed.
Value stored in the infile variable is not a file object, it is a list. Because your called readlines method.
Doing
infile = open(infilename, "r").readlines()
you have read the lines of the file and assign the list to infile. But you haven't assigne the file to a variable.
If you want to explicitly close the file:
someFile = open(infilename, "r")
infile = someFile.readlines()
...
someFile.close()
or use with which close the file automatically:
with open(infilename, "r") as someFile:
infile = someFile.readlines()
....
print "the file here is closed"
infile = open(infilename, "r")
# this resp. infile is a file object (where you can call the function close())
infile = open(infilename, "r").readlines()
# this resp. infile is a list object, because readlines() returns a list
That's all.
As #Ffisegydd mentioned above, make use of with statement introduced in in Python 2.5. It will automatically close the file for you after the nested code block. And yet, in case an exception also happened the file will be closed before the exception is caught, pretty handy.
For more info, checkout this out on the context manager:
https://docs.python.org/2/library/contextlib.html
I actually make use of the context manager to achieve somewhat some level of maintainability.
I would use this more memory efficient code:
infilename = "Rate.txt"
with open (infilename) as f:
next(f) # Skip header
dat = None
for line in f:
if dat: # Skip last line
_, _, _, strfield, CheckNumeric, CheckNumeric1 = dat.split()
dat = line
I am trying to replace text in a text file by reading each line, testing it, then writing if it needs to be updated. I DO NOT want to save as a new file, as my script already backs up the files first and operates on the backups.
Here is what I have so far... I get fpath from os.walk() and I guarantee that the pathmatch var returns correctly:
fpath = os.path.join(thisdir, filename)
with open(fpath, 'r+') as f:
for line in f.readlines():
if '<a href="' in line:
for test in filelist:
pathmatch = file_match(line, test)
if pathmatch is not None:
repstring = filelist[test] + pathmatch
print 'old line:', line
line = line.replace(test, repstring)
print 'new line:', line
f.write(line)
But what ends up happening is that I only get a few lines (updated correctly, mind you, but repeated from earlier in the file) corrected. I think this is a scoping issue, afaict.
*Also: I would like to know how to only replace the text upon the first instance of the match, for ex., I don't want to match the display text, only the underlying href.
First, you want to write the line whether it matches the pattern or not. Otherwise, you're writing out only the matched lines.
Second, between reading the lines and writing the results, you'll need to either truncate the file (can f.seek(0) then f.truncate()), or close the original and reopen. Picking the former, I'd end up with something like:
fpath = os.path.join(thisdir, filename)
with open(fpath, 'r+') as f:
lines = f.readlines()
f.seek(0)
f.truncate()
for line in lines:
if '<a href="' in line:
for test in filelist:
pathmatch = file_match(line, test)
if pathmatch is not None:
repstring = filelist[test] + pathmatch
line = line.replace(test, repstring)
f.write(line)
Open the file for read and copy all of the lines into memory. Close the file.
Apply your transformations on the lines in memory.
Open the file for write and write out all the lines of text in memory.
with open(filename, "r") as f:
lines = (line.rstrip() for line in f)
altered_lines = [some_func(line) if regex.match(line) else line for line in lines]
with open(filename, "w") as f:
f.write('\n'.join(altered_lines) + '\n')
A (relatively) safe way to replace a line in a file.
#!/usr/bin/python
# defensive programming style
# function to replace a line in a file
# and not destroy data in case of error
def replace_line(filepath, oldline, newline ):
"""
replace a line in a temporary file,
then copy it over into the
original file if everything goes well
"""
# quick parameter checks
assert os.exists(filepath) # !
assert ( oldline and str(oldline) ) # is not empty and is a string
assert ( newline and str(newline) )
replaced = False
written = False
try:
with open(filepath, 'r+') as f: # open for read/write -- alias to f
lines = f.readlines() # get all lines in file
if oldline not in lines:
pass # line not found in file, do nothing
else:
tmpfile = NamedTemporaryFile(delete=True) # temp file opened for writing
for line in lines: # process each line
if line == oldline: # find the line we want
tmpfile.write(newline) # replace it
replaced = True
else:
tmpfile.write(oldline) # write old line unchanged
if replaced: # overwrite the original file
f.seek(0) # beginning of file
f.truncate() # empties out original file
for tmplines in tmpfile:
f.write(tmplines) # writes each line to original file
written = True
tmpfile.close() # tmpfile auto deleted
f.close() # we opened it , we close it
except IOError, ioe: # if something bad happened.
printf ("ERROR" , ioe)
f.close()
return False
return replaced and written # replacement happened with no errors = True
(note: this replaces entire lines only , and all of the lines that match in the file)