I am having an issue with a timetracker program, where I am trying to identify a line in a file by iterating over it and then writing the lines UNLESS there is anything with
This is reading to the end of the file
print(today.read())
When you start iterating here, you're already at the end
for line in today.readline():
so the for loop will never be entered. You need to reopen the file or seek back to the beginning.
Another problem is that you are iterating over the first line. You probably meant
for line in today:
Regardless, it's generally not a great idea to write to the same file you are reading (eg. consider the mess the file would be in if the computer gets reset partway through)
Better to write a temporary file and replace.
If the files are very small, you could read the file into a list in memory and then rewrite the file out again.
A better idea, before you go too far is to use a database such as the sqlite
module (which is builtin to Python)
Well you can do the following also:
with open("input.txt",'r') as infile, open("output.txt",'w') as outfile:
# code here
outfile.write(line)
In your file loop, you can do something like:
if delete:
continue
to skip the line that you don't want to write to the output file.
The problem comes from reading and writing the same file. Here is some explanation on that.
Good reference (Beginner Python: Reading and writing to the same file)
So when in r+
mode, both reading and writing to the file move the file pointer forward.
So let's look at your example. First you do a readline. This moves the file pointer to the next line. You check if the line you just read is valid or not and write it if it is.
The problem is that you just overwrote the next line, not the previous one! So your code is really messing up your data.
Bascially it's really hard (and inefficient if the file is large) to do want you want to do right. You can't arbitrarily delete bytes out of the middle of a file. For each line you wanted to delete, you'd have to write the rest of the data over it then truncate the file at the end to delete the freed space.
You should take the advice of the other answers and either output to another file or stdout
.
today.readline()
returns a single line. The for
-loop iterates over characters in that line. And as @gnibbler pointed out the today
file is at the end of file at the time today.readline()
is called (so it returns an emtpy string).
In general, to delete something in the middle of a file you need to replace the file completely. fileinput
module can help:
import fileinput
for line in fileinput.input([date], inplace=1):
if delete not in line:
print line, # stdout is redirected to the `date` file
Here's almost the same but without fileinput
:
import os
from tempfile import NamedTemporaryFile
filename = date
dirpath = os.path.dirname(filename)
with open(filename) as file, NamedTemporaryFile("w", dir=dirpath) as outfile:
for line in file:
if delete not in line:
print >>outfile, line, # copy old content
outfile.delete = False # don't delete outfile
os.remove(filename) # rename() doesn't overwrite on Windows
os.rename(outfile.name, filename) # or just `os.replace` in Python 3.3+