删除文件中的特定行(python)

比方说,我有一个充满绰号的文本文件,我怎样才能从该文件中删除一个特定的昵称?

假设你的文件是每行一个昵称的格式,使用这个。

首先,打开文件:

 f = open("yourfile.txt","r") 

接下来,从文件中获取所有行:

 lines = f.readlines() 

现在你可以closures文件了:

 f.close() 

并以写入模式重新打开:

 f = open("yourfile.txt","w") 

然后,写回你的行,除了你想要删除的行。 您可能需要将"\n"更改为文件结尾的任何行。

 for line in lines: if line!="nickname_to_delete"+"\n": f.write(line) 

最后,再次closures文件。

 f.close() 

解决这个问题只有一个单一的打开:

 f = open("target.txt","r+") d = f.readlines() f.seek(0) for i in d: if i != "line you want to remove...": f.write(i) f.truncate() f.close() 

此解决scheme以r / w模式(“r +”)打开文件,并使用seek重置f-指针,然后截断以删除上次写入后的所有内容。

最好和最快的select,而不是将所有内容存储在一个列表中,并重新打开文件来写它,在我看来是在其他地方重写文件。

 with open("yourfile.txt","r") as input: with open("newfile.txt","wb") as output: for line in input: if line!="nickname_to_delete"+"\n": output.write(line) 

而已! 在一个循环中,只有一个你可以做同样的事情。 这将会更快。

第一遍读取行和第二遍更改(删除特定行)的问题是,如果文件大小很大,则会耗尽RAM。 相反,更好的方法是逐行读取行,并将其写入单独的文件中,从而消除不需要的行。 我已经运行这种方法的文件大小为12-50 GB,RAM的使用率几乎保持不变。 只有CPU周期显示正在处理中。

如果你把整个文件放到内存中,这个问题并不是一个好的解决办法,我知道现在每个人都有大量的内存,但是考虑一下这个文件是几GB的日志还是其他东西。

更好的方法是将它逐行复制到一个新的文件,而不是删除第一个或类似的东西

一般来说,你不能; 你必须再次写整个文件(至less从更改到最后)。

在某些特定情况下,你可以做得比这更好 –

如果所有的数据元素的长度都是相同的并且没有特定的顺序,并且您知道要删除的数据元素的偏移量,则可以将最后一个项目复制到要删除的项目上,并截断最后一个项目之前的文件;

或者您可以在保存的数据元素中使用“这是错误的数据,跳过它的值”或保留“此项目已被删除”标志覆盖数据块,以便您可以将其标记为已删除,而无需另行修改文件。

对于短文档(100 KB以下的任何内容),这可能是矫枉过正的。

如果你使用Linux,你可以尝试下面的方法。
假设你有一个名为animal.txt的文本文件:

 $ cat animal.txt dog pig cat monkey elephant 

删除第一行:

 >>> import subprocess >>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt']) 

然后

 $ cat animal.txt pig cat monkey elephant 

我想如果你把文件读入列表中,那么你可以迭代列表来寻找你想要删除的昵称。 您可以高效地完成这个任务,而无需创build额外的文件,但是您必须将结果写回源文件。

以下是我可以这样做的:

 import, os, csv # and other imports you need nicknames_to_delete = ['Nick', 'Stephen', 'Mark'] 

我假设nicknames.csv包含数据如:

 Nick Maria James Chris Mario Stephen Isabella Ahmed Julia Mark ... 

然后将文件加载到列表中:

  nicknames = None with open("nicknames.csv") as sourceFile: nicknames = sourceFile.read().splitlines() 

接下来,迭代到列表以匹配您的input删除:

 for nick in nicknames_to_delete: try: if nick in nicknames: nicknames.pop(nicknames.index(nick)) else: print(nick + " is not found in the file") except ValueError: pass 

最后,将结果写回文件:

 with open("nicknames.csv", "a") as nicknamesFile: nicknamesFile.seek(0) nicknamesFile.truncate() nicknamesWriter = csv.writer(nicknamesFile) for name in nicknames: nicknamesWriter.writeRow([str(name)]) nicknamesFile.close() 

这是一个基于@Lother在这里提出的解决scheme的“分支”,我相信这应该被认为是正确的答案。

对于像这样的内容的文件:

 $ cat file.txt 1: october rust 2: november rain 3: december snow 

这个来自Lother的解决scheme的工作正常:

 #!/usr/bin/python3.4 with open("file.txt","r+") as f: new_f = f.readlines() f.seek(0) for line in new_f: if "snow" not in line: f.write(line) f.truncate() 

主要的改进是使用with open ,它放弃了f.close()的使用,以及脚本是否包含string的评估方式。

我喜欢这个答案中解释的fileinput方法: 从文本文件中删除一行(python)

说例如我有一个文件中有空行,我想删除空行,这是我如何解决它:

 import fileinput import sys for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)): if len(line) > 1: sys.stdout.write(line) 

注意:在我的情况下,空行长度为1

可能你已经得到了正确的答案,但是这是我的。 我使用两个文件,而不是使用列表来收集未经过滤的数据( readlines()方法)。 一个是保存主数据,第二个是删除特定string时过滤数据。 这是一个代码:

 main_file = open('data_base.txt').read() # your main dataBase file filter_file = open('filter_base.txt', 'w') filter_file.write(main_file) filter_file.close() main_file = open('data_base.txt', 'w') for line in open('filter_base'): if 'your data to delete' not in line: # remove a specific string main_file.write(line) # put all strings back to your db except deleted else: pass main_file.close() 

希望你会发现这有用! 🙂

将文件行保存在列表中,然后删除要删除的行的列表,并将剩余行写入新文件

 with open("file_name.txt", "r") as f: lines = f.readlines() lines.remove("Line you want to delete\n") with open("new_file.txt", "w") as new_f: for line in lines: new_f.write(line) 

取文件的内容,用换行符将它拆分成一个元组。 然后,访问你的元组的行号,join你的结果元组,并覆盖到文件。