1

I am trying to delete 38 lines of text after coming across a certain phrase in a .txt file in Python, while still printing the rest of the text.

The code I currently have is

with open('text_file.txt','r') as f:
lines = f.readlines()
for line in lines:
    if "certain_phrase" in line:
        for num in range(38):
            del line
    else:
        print(line,end='')

However, I keep getting the following error:

Traceback (most recent call last):
  File "C:\<location of file>\python_program.py", line 6, in <module>
    del line
NameError: name 'line' is not defined

Does anyone have any suggestions or clues as to why it does not recognize "line" once I've put it inside the for loop below? Additionally, is there a better way to execute this kind of program?

3
  • 2
    this code will not do what you want it to do even if there was no error Commented Apr 3, 2015 at 15:09
  • it does not know the variable line at the second iteration of your for num in ... loop because you just deleted it during previous iteration and did not redefine it in between Commented Apr 3, 2015 at 15:11
  • First advice: no need for line 2 when reading a file (it's a waste of memory since you store the entire file in memory instead of reading it line by line) => for line in f Commented Apr 3, 2015 at 15:15

4 Answers 4

3

You would need to remove from the list, you cannot del the line, the easiest way is to write to a temp file and copy after if you want to modify the file, if you just want to print ignoring the 38 line replace write with print:

 with open('in.txt','r') as f,open('temp.txt','w') as temp:
    for line in f:
        if "phrase" in line:
            for i in range(38):
                next(f) # skip 38 lines
        else:
            temp.write(line)

Then use shutil to move the file:

import shutil

shutil.move("temp.txt","in.txt")

You can also use a NamedTemporaryFile:

from tempfile import NamedTemporaryFile

with open('file.txt','r') as f, NamedTemporaryFile(dir=".",delete=False) as  temp:
    for line in f:
        if "phrase" in line:
            for i in range(38):
                next(f)
        else:
            temp.write(line)

import shutil
shutil.move(temp.name,"file.txt")

The only potential problem I see is if the phrase is in one of the 38 ignored lines and you should also remove the next 38 lines from there.

To ignore until a second phrase, keep looping in the inner loop until you find the second phrase then break:

with open('in.txt','r') as f, NamedTemporaryFile(dir=".", delete=False) as temp:
    for line in f:
        if "phrase" in line:
            for _line in f:
                if "phrase2" in _line:
                    break
        else:
            temp.write(line)
Sign up to request clarification or add additional context in comments.

4 Comments

This works exceptionally well! Thank you so much! Very useful to know!
couldn't you use a while loop and reset the counter if the phrase is within the 38 ignored lines?
I know that "there should be one-- and preferably only one --obvious way to do it," but I think both methods are equally good.
@cody yes do the check in the inner loop and break if you find the second phrase looping over f instead of using range. I will edit when i get back on my comp
1

Instead of trying to delete lines from a file, write a new file based on the old one. The following uses __next__() to skip over lines yielded by the generator.

with open('text_file.txt','r') as f, open('text_file_mod.txt', 'w') as w:
    for line in f:
        w.write(line)
        if "certain_phrase" in line:
            for num in range(38): # skip 38 lines
                next(f)

If you're doing this from the interactive interpreter, you can prevent it from spitting out returned values by saving the results of next(f) and w.write(line) to variables.

Comments

0

del line actually deletes the variable line, meaning that when you try to do that a second time, it doesn't work, because line isn't defined anymore. You can loop over indices to find the line, break, then delete the next 38 lines:

with open('text_file.txt','r') as f:
lines = f.readlines()
for i in range(len(lines)):
    if "certain_phrase" in lines[i]:
        break
    else:
        print(line,end='')
for num in range(38):
    del lines[i]

Comments

0
with open('temp.txt','r') as fin:
    for line in fin:
        print(line,end="") #you want to print the phrase, right?
        if "certain_phrase" in line:
            for _ in range(38):
                next(line)

1 Comment

I'm pretty sure this does not do what the asker wanted... this deletes the first 38 lines that contains "certain_phrase" as opposed to reading until it finds "certain_phrase" in a line and then deleting (or really skipping) the next 38 lines

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.