So I have a file with some lines of text:
here's a sentence
look! another one
here's a third one too
and another one
one more
and I have some code that takes the each line and puts it into a list and then reverses the order of the whole list but now I don't know how to write each line back to the file and delete the existing ones in the text file.
Also when I run this code:
file_lines = open(file_name).readlines()
print(file_lines)
file_lines.reverse()
print(file_lines)
everything works and the line order is reversed, but when I run this code:
text_file = open(file_name, "w")
file_lines = open(file_name).readlines()
print(file_lines)
file_lines.reverse()
print(file_lines)
for line in file_lines:
text_file.write(line)
it prints empty lists for some reason.
You can fix it by doing just 2 little changes in your script.
Use \r+ in place of \w+
Before performing write operation, place file position indicator to the beginning
text_file.seek(0)
» rw_file.txt - before operation
here's a sentence
look! another one
here's a third one too
and another one
one more
Below is your modified script to reverse the content of file (It worked).
def reverseFile(file_name):
text_file = open(file_name, "r+") # Do not use 'w+', it will erase your file content
file_lines = [line.rstrip('\n') for line in text_file.readlines()]
file_lines.reverse()
print(file_lines)
text_file.seek(0) # Place file position indicator at beginning
for line_item in file_lines:
text_file.write(line_item+"\n")
reverseFile("rw_file.txt")
» rw_file.txt - after operation
one more
and another one
here's a third one too
look! another one
here's a sentence
If you open the file in 'w' mode, the file is erased. From the docs:
'w' for only writing (an existing file with the same name will be
erased)
You should also use the with keyword:
It is good practice to use the with keyword when dealing with file
objects. The advantage is that the file is properly closed after its
suite finishes...
I would recommend you read the contents of the file first, process that data, and then write:
def reverseFile(file_name):
with open(file_name, 'r') as f:
file_lines = [line.rstrip('\n') for line in f.readlines()]
file_lines.reverse()
with open(file_name, "w") as f:
for line in file_lines:
f.write(line + '\n')
reverseFile('text_lines.txt')
Related
I have a txt file with 5 lines. I want to delete the first line copied after typing the text in the first line on the last line.
Example:
1
2
3
4
5
After:
2
3
4
5
1
my attempt
with open("equasisemail.txt", 'r') as file:
data = file.read().splitlines(True)
with open ("equasisemail.txt",'w') as fi:
fi.writelines(data[1:])
i use this to delete the first line.
read the lines using readlines (don't splitlines else you lose line terminator). Then write back the file using writelines then write the final line with a simple write
with open("equasisemail.txt", 'r') as file:
data = file.readlines()
# make sure the last line ends with newline (may not be the case)
if not data[-1].endswith("\n"):
data[-1] += "\n"
with open ("equasisemail.txt",'w') as fi:
fi.writelines(data[1:])
fi.write(data[0])
careful as if something bad happens during the write the file is destroyed. Better use another name, then rename once writing has completed. In which case what can be done is reading & writing at almost the same time on 2 separate filenames:
with open("equasisemail.txt", 'r') as fr,open ("equasisemail2.txt",'w') as fw:
first_line = next(fr) # manual iterate to get first line
for line in fr:
fw.write(line)
if not line.endswith("\n"):
fw.write("\n")
fw.write(first_line)
os.remove("equasisemail.txt")
os.rename("equasisemail2.txt","equasisemail.txt")
safer & saves memory. Fails if the file is empty. Test it first.
note: both solutions support files that don't end with a newline character.
To edit a file without creating a new file you can save the contents of the file to main memory, then open it in write mode:
input = open("email.txt", "r")
lines = input.readlines()
input.close()
output = open("email.txt", "w")
for i in range(1, len(lines)):
output.write(lines[i].strip() + "\n")
output.write(lines[0])
I am trying to create a script that will take each line in my text file which includes one rule name in each of them. The first script I created worked (finished) but would delete everything in the file. I have been googling for past hour or so trying to take examples and apply them on my own but keep failing. The current script is as follows.
with open('TDAppendlist.txt', 'w') as file:
for line in file:
s = ('""')
seq = (file)
s.join(seq)
with open('TDAppendlist.txt') as file:
line = file.readlines()
for line in file:
line.join('"' + line + '"')
Neither of them are working. Could someone please point me in the correct direction? Thank you all for reading.
First, we'll read all the lines of the file into a list, then we can change them, and finally write them back to the file.
with open('TDAppendlist.txt') as file:
lines = list(file)
with open('TDAppendlist.txt', 'w') as file:
file.write('\n'.join(['"{}"'.format(line.rstrip('\n')) for line in lines]))
That last line can be written out to be more clear
lines = (line.rstrip('\n') for line in lines)
lines = ('"{}"'.format(line) for line in lines)
lines = '\n'.join(lines)
file.write(lines)
This produces an output file TDAppendlist_out that is just like the input, but with quotes surrounding the lines:
with open('TDAppendlist.txt', 'r') as f:
with open('TDAppendlist_out.txt', 'w') as f_out:
for line in f:
f_out.write('\"{}\"'.format(line))
This keeps the input file intact as is should you need it later, and avoids putting everything in the input file into memory all at once.
I wrote the following python code snippet to append a lower p character to each line of a txt file:
f = open('helloworld.txt','r')
for line in f:
line+='p'
print(f.read())
f.close()
However, when I execute this python program, it returns nothing but an empty blank:
zhiwei#zhiwei-Lenovo-Rescuer-15ISK:~/Documents/1001/ass5$ python3 helloworld.py
Can anyone tell me what's wrong with my codes?
Currently, you are only reading each line and not writing to the file. reopen the file in write mode and write your full string to it, like so:
newf=""
with open('helloworld.txt','r') as f:
for line in f:
newf+=line.strip()+"p\n"
f.close()
with open('helloworld.txt','w') as f:
f.write(newf)
f.close()
well, type help(f) in shell, you can get "Character and line based layer over a BufferedIOBase object, buffer."
it's meaning:if you reading first buffer,you can get content, but again. it's empty。
so like this:
with open(oldfile, 'r') as f1, open(newfile, 'w') as f2:
newline = ''
for line in f1:
newline+=line.strip()+"p\n"
f2.write(newline)
open(filePath, openMode) takes two arguments, the first one is the path to your file, the second one is the mode it will be opened it. When you use 'r' as second argument, you are actually telling Python to open it as an only reading file.
If you want to write on it, you need to open it in writing mode, using 'w' as second argument. You can find more about how to read/write files in Python in its official documentation.
If you want to read and write at the same time, you have to open the file in both reading and writing modes. You can do this simply by using 'r+' mode.
It seems that your for loop has already read the file to the end, so f.read() return empty string.
If you just need to print the lines in the file, you could move the print into for loop just like print(line). And it is better to move the f.read() before for loop:
f = open("filename", "r")
lines = f.readlines()
for line in lines:
line += "p"
print(line)
f.close()
If you need to modify the file, you need to create another file obj and open it in mode of "w", and use f.write(line) to write the modified lines into the new file.
Besides, it is more better to use with clause in python instead of open(), it is more pythonic.
with open("filename", "r") as f:
lines = f.readlines()
for line in lines:
line += "p"
print(line)
When using with clause, you have no need to close file, this is more simple.
I have a file and I would like to read the first line and write from the second.
with open(file_path, 'r+') as f:
f.readline()
for values in my_array:
f.write("%s=%s" % (str(values[0]), str(values[1])))
Any suggestion?
You can't write on a file while reading it.
Two solutions :
Have a second file where you rewrite your first line and then write the second one :
with open(file_path, 'r+') as f:
line = f.readline()
with open('another_file.txt', 'w') as outfile:
outfile.write(line)
outfile.write(...) # Whatever you want on your second line
Store everything you want to write in memory and then write over your previous file (Which I don't recommend, if something happens midway and your file is stil overwritten, all previous data will be lost).
When editing the contents of a file I have been using the approach of:
Open the file in read mode
Convert file contents to a string with the .read() method and assign to another variable
Close the file
Do things to the string
Open the original file in write mode
Write the string to file
Close the file
For example:
fo = open('file.html', r)
fo_as_string = fo.read()
fo.close()
# # #
# do stuff to fo_as_string here
# # #
fo = open('file.html', w)
fo.write(fo_as_string)
fo.close()
I now find myself in the situation however where I need to remove any white space at the beginning of lines and I think as I have converted the file object to a string there is no way to target this whitespace, at a 'line' level, with string methods like lstrip and rstrip.
So I guess I am after logic advice on how to retain the flexibility of having the file contents as a string for manipulation, but also be able to target lines within the string for specific line manipulation when required, as in the example above.
Use a for-loop, a for-loop over a file object returns one line at a time.
#use `with` statement for handling files, it automatically closes the file for you.
with open('file.html') as fo, open('file1.html', 'w') as fo1:
for line in fo: #reads one line at a time, memory efficient
#do something with line, line.strip()
fo1.write(line + '\n') #write line to to fo1
If you're trying to modify the same file then use fileinput module:
import fileinput
for line in fileinput.input('file.html', inplace = True):
#do something with line
print line #writes the line back to 'file.html'
You can also get individual lines from file.read() as well, split it using:
fo_as_string = fo.read()
lines = fo_as_string.splitlines()
But file.read() loads the whole file into memory, so it is not much memory efficient.
Other alternatives are f.readlines() and list(f), both return a list of all lines from the file object.
Depending on the size of the file, and the processes you want to do to each line, there are a couple of answers that might work for you.
First, if you're intent on keeping the entire file in memory while you process it, you could save it as a list of lines, process some or all of the lines, and rejoin them with your standard line delimiter when you wish to write them to disk:
linesep = '\n'
with open('file.html', 'r') as fin:
input_lines = fin.readlines()
# Do your per-line transformation
modified_lines = [line.lstrip() for line in input_lines]
# Join the lines into one string to do whole-string processing
whole_string = linesep.join(modified_lines)
# whatever full-string processing you're looking for, do here
# Write to disk
with open('file1.html', 'w') as output_file:
output_file.write(whole_string)
Or you could specify your own line separator, and do the input parsing by hand:
linesep = '\n'
input_lines_by_hand = fin.read.split(linesep)