如何使用Python按行号从文本文件中删除一行

5

这里是一个文本文件的示例

the bird flew
the dog barked
the cat meowed

这是我用来查找要删除短语的行号的代码:

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

我该添加什么才能删除行号(num)?我已经尝试过:
lines = myFile.readlines()
del line[num]

但是这并不能起作用,我该如何处理?


可能是删除文件中特定行(Python)的重复问题。 - TerryA
7个回答

8
您可以使用fileinput模块来更新文件 - 请注意,这将删除包含该短语的所有行:
import fileinput

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

1
如果您已经知道要从变量n中删除的行的索引,您可以将条件更改为if fileinput.lineno() == n: - tripleee
你需要在顶部加上 from __future__ import print_function 吗?我尝试使用 end='' 时出现错误。即使进行了导入,我仍然会遇到错误。抱歉,我是 Python 新手。 - Nick
不好意思,忘了 from __future__ import print_function 必须放在第一行。 odd。 - Nick
1
@Nick 如果你正在使用Python 2.x,那么你可以使用print line,来实现相同的效果(尾随逗号会抑制默认的换行符 - 类似于3.x的print函数中的end='',但并不完全相同)。 - Jon Clements
我不知道为什么这个被选为答案,因为它对文件本身实际上没有任何作用。问题是要就地更新文件,而不是打印除特定行以外的所有内容... - MrDysprosium

3
我找到了另一个高效的解决方案,可以避免对文件对象中的所有行进行不太优雅和麻烦的计数:
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)

对于那些需要详细解释的人:

(1)创建一个包含您想要删除的行号的整数值的变量。假设我想要删除第三行:

del_line = 3

(2) 打开文本文件并将其放入文件对象中。目前只需要读取模式。然后,将其内容放入列表中:

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

(3) 现在每一行都应该是“list”中的一个索引元素。您可以通过删除表示要删除的行的元素来继续进行:

del list[del_line - 1]

如果你已经得到了需要从用户输入中删除的行号,确保将其转换为整数,因为它很可能会以字符串格式出现(如果您使用了 "input()")。

要减去1是因为列表元素索引从0开始。然而,我假设您(或用户)从第1行开始计数,在这种情况下,您需要减去1才能捕获列表中的正确元素。

(4)再次以“写模式”打开列表文件,重写完整文件。之后,遍历已更新的列表,将“list”的每个元素重新写入文件中。您不必担心换行符,因为在将原始文件的内容放入列表中时(步骤2),\ n转义字符也将复制到列表元素中:

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

当我想让用户决定在某个文本文件中删除哪一行时,以下代码对我很有用。我认为Martijn Pieters的回答做了类似的事情,但他的解释太少了,我无法理解。


3

一位名叫gnibbler的用户在另一个帖子中发布了类似的内容。

直接修改文件,将有问题的行替换为空格,这样文件的其余部分就不需要在磁盘上重新排序。如果修复行比要替换的行还长,你也可以直接在原地进行修复。

如果其他程序可以更改为输出文件偏移量而不是行号,那么您可以直接将偏移量分配给p,无需使用for循环。

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

2
假设num是要删除的行数:
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')

2
使用Numpy进行这项任务会有一些奇怪的点。它是否提供任何真正的好处(例如在某些情况下可能更快)? - tripleee
1
从来没有想到过在这种情况下会用到numpy。谢谢,这对我来说是新的经验 +1。 - Pygirl

0

你从开始计数,但 Python 的索引总是从零开始。

将你的行数计数从开始:

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

或者从 num 中减去一,从 lines 中删除(而不是 line):

del lines[num - 1]

请注意,为了使您的.readlines()调用返回任何行,您需要先重新打开文件或将其定位到开头:
myFile.seek(0)

@derpyherp:啊,你也打错字了;是 line 而不是 lines - Martijn Pieters
@derpyherp: 更新内容包括有关两次读取同一文件的建议。但是你为什么要绕这个迂回路呢?为什么不直接逐行读取,边读边将其添加到列表中,并跳过不需要的那一行呢? - Martijn Pieters
我需要这个程序能够找到包含指定短语的行号,然后删除该行。 - derpyherp
@derpyherp: 从哪里删除那一行?原始文件中吗? - Martijn Pieters
@derpyherp:你已经解决了枚举部分。你看过链接的重复内容了吗? - Martijn Pieters

0

尝试一下

lines = myFile.readlines()  

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

0

实现 @atomh33ls 的numpy方法 所以你想删除文件中包含phrase字符串的任何行,对吗?而不仅仅是删除phrase字符串。

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')

文本文件在哪里,

the bird flew
the dog barked
the cat meowed

生成

the bird flew
the cat meowed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接