derpyherp
derpyherp

Reputation: 525

How to delete a line from a text file using the line number in python

here is an example text file

the bird flew
the dog barked
the cat meowed

here is my code to find the line number of the phrase i want to delete

phrase = 'the dog barked'

with open(filename) as myFile:
    for num, line in enumerate(myFile, 1):
        if phrase in line:
            print 'found at line:', num

what can i add to this to be able to delete the line number (num) i have tried

lines = myFile.readlines()
del line[num]

but this doesnt work how should i approach this?

Upvotes: 5

Views: 39287

Answers (7)

Subham
Subham

Reputation: 411

Implementing @atomh33ls numpy approach So you want to delete any line in the file that contain the phrase string, right? instead of just deleting the phrase string

import numpy as np

phrase = 'the dog barked'

nums = [] 

with open("yourfile.txt") as myFile:
    for num1, line in enumerate(myFile, 0):
    # Changing from enumerate(myFile, 1) to enumerate(myFile, 0)
        if phrase in line:
            nums.append(num1)

a=np.genfromtxt("yourfile.txt",dtype=None, delimiter="\n", encoding=None ) 
      
with open('yourfile.txt','w') as f:
    for el in np.delete(a,nums,axis=0):
        f.write(str(el)+'\n')

where text file is,

the bird flew
the dog barked
the cat meowed

produces

the bird flew
the cat meowed

Upvotes: 0

Rob
Rob

Reputation: 31

I found another solution that works efficiently and gets by without doing all the icky and not so elegant counting of lines within the file object:

del_line = 3    #line to be deleted: no. 3 (first line is no. 1)

with open("textfile.txt","r") as textobj:
    list = list(textobj)    #puts all lines in a list

del list[del_line - 1]    #delete regarding element

    #rewrite the textfile from list contents/elements:
with open("textfile.txt","w") as textobj:
    for n in list:
        textobj.write(n)

Detailed explanation for those who want it:

(1) Create a variable containing an integer value of the line-number you want to have deleted. Let's say I want to delete line #3:

del_line = 3

(2) Open the text file and put it into a file-object. Only reading-mode is necessary for now. Then, put its contents into a list:

with open("textfile.txt","r") as textobj:
    list = list(textobj)

(3) Now every line should be an indexed element in "list". You can proceed by deleting the element representing the line you want to have deleted:

del list[del_line - 1]

At this point, if you got the line no. that is supposed to be deleted from user-input, make sure to convert it to integer first since it will be in string format most likely(if you used "input()").

It's del_line - 1 because the list's element-index starts at 0. However, I assume you (or the user) start counting at "1" for line no. 1, in which case you need to deduct 1 to catch the correct element in the list.

(4) Open the list file again, this time in "write-mode", rewriting the complete file. After that, iterate over the updated list, rewriting every element of "list" into the file. You don't need to worry about new lines because at the moment you put the contents of the original file into a list (step 2), the \n escapes will also be copied into the list elements:

with open("textfile.txt","w") as textobj:
    for n in list:
        textobj.write(n)

This has done the job for me when I wanted the user to decide which line to delete in a certain text file. I think Martijn Pieters's answer does sth. similar, however his explanation is to little for me to be able to tell.

Upvotes: 3

Lee
Lee

Reputation: 31050

Assuming num is the line number to remove:

import numpy as np
a=np.genfromtxt("yourfile.txt",dtype=None, delimiter="\n") 
with open('yourfile.txt','w') as f:    
    for el in np.delete(a,(num-1),axis=0):
        f.write(str(el)+'\n')

Upvotes: 2

aar cee
aar cee

Reputation: 249

Try

lines = myFile.readlines()  

mylines = [x for x in lines if x.find(phrase) < 0]  

Upvotes: 0

HKImpact
HKImpact

Reputation: 620

A user by the name of gnibbler posted something similar to this on another thread.

Modify the file in place, offending line is replaced with spaces so the remainder of the file does not need to be shuffled around on disk. You can also "fix" the line in place if the fix is not longer than the line you are replacing

If the other program can be changed to output the fileoffset instead of the line number, you can assign the offset to p directly and do without the for loop

import os
from mmap import mmap

phrase = 'the dog barked'
filename = r'C:\Path\text.txt'

def removeLine(filename, num):
    f=os.open(filename, os.O_RDWR)
    m=mmap(f,0)
    p=0
    for i in range(num-1):
        p=m.find('\n',p)+1
    q=m.find('\n',p)
    m[p:q] = ' '*(q-p)
    os.close(f)

with open(filename) as myFile:
    for num, line in enumerate(myFile, 1):
        if phrase in line:            
            removeLine(filename, num)
            print 'Removed at line:', num

Upvotes: 3

Jon Clements
Jon Clements

Reputation: 142166

You could use the fileinput module to update the file - note this will remove all lines containing the phrase:

import fileinput

for line in fileinput.input(filename, inplace=True):
    if phrase in line:
        continue
    print(line, end='')

Upvotes: 8

Martijn Pieters
Martijn Pieters

Reputation: 1122252

You start counting at one, but python indices are always zero-based.

Start your line count at zero:

for num, line in enumerate(myFile):  # default is to start at 0

or subtract one from num, deleting from lines (not line):

del lines[num - 1]

Note that in order for your .readlines() call to return any lines, you need to either re-open the file first, or seek to the start:

myFile.seek(0)

Upvotes: 0

Related Questions