Reputation: 19
I am trying to delete all the lines in a text file after a line that contains a specific string. What I am trying to do is find the number of the line in said file and rewrite the whole text up until that line.
The code that I'm trying is the following:
import itertools as it
with open('sampletext.txt', "r") as rf:
for num, line in enumerate(rf, 1): #Finds the number of the line in which a specific string is contained
if 'string' in line:
print(num)
with open('sampletext_copy.txt', "w") as wf:
for line in it.islice(rf, 0, num):
wf.write(line)
Also would appreciate any tips on how to do this. Thank you!
Upvotes: 1
Views: 1523
Reputation: 155428
Just to complement Donut's answer, if you want to modify the file in-place, there's a much more efficient solution:
with open('sampletext.txt', "r+") as f:
for line in iter(f.readline, ''): # Can't use for line in f: because it disables
# tell for txt
# Or for walrus lovers:
# while line := f.readline():
if 'string' in line:
f.seek(0, 1) # Needed to ensure underlying handle matches logical read
# position; f.seek(f.tell()) is logically equivalent
f.truncate()
break
If issue #70346 is ever fixed (so calling truncate
on a file actually truncate
s at the logical position, not the arbitrary position of the underlying raw handle that's likely advanced a great deal due to buffering), this simpler code would work:
with open('sampletext.txt', "r+") as f:
for line in f:
if 'string' in line:
f.truncate()
break
If you want to delete the tested-for line as well, not just the following lines, you need to store the cookie before reading each line so you can back up when you find it (sticking to walrus this time, since most people can probably use it by now):
with open('sampletext.txt', "r+") as f:
cookie = 0 # Don't need tell to seek back to start of file if first line matches
while line := f.readline():
if 'string' in line:
f.seek(cookie) # Revert to position before we read in most recent line
f.truncate()
break
cookie = f.tell() # Save off position cookie prior to reading next line
Upvotes: 1
Reputation: 7812
In case if you want to apply changes to original file, it's possible to do using .truncate()
method of file object:
with open(r"sampletext.txt", "r+") as f:
while line := f.readline():
if line.rstrip() == "string": # line.startswith("string")
f.truncate(f.tell()) # removes all content after current position
break
Here we iterating over file until reach this specific line and resize stream to size of bytes we've already read (to get it we use .tell()
).
Upvotes: 0
Reputation: 112825
You could do it like this:
with open('sampletext.txt', "r") as rf, open('sampletext_copy.txt', "w") as wf:
for line in rf:
if 'string' in line:
break
wf.write(line)
Basically, you open both files at the same time, then read the input file line-by-line. If string
is in the line, then you're done - otherwise, write it to the output file.
Upvotes: 2