删除文件中的特定行(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你的结果元组,并覆盖到文件。