假设我有一个充满昵称的文本文件。如何使用Python从该文件中删除特定的昵称?
首先,打开文件并获取文件中的所有行。然后以写模式重新打开文件,并将除了要删除的那一行之外的行写回文件:
with open("yourfile.txt", "r") as f:
lines = f.readlines()
with open("yourfile.txt", "w") as f:
for line in lines:
if line.strip("\n") != "nickname_to_delete":
f.write(line)
你需要在比较时使用strip("\n")
函数来移除换行符,因为如果你的文件没有以换行符结尾,则最后一个line
也不会有。
这个问题的解决方案只需要一个打开:
with open("target.txt", "r+") as f:
d = f.readlines()
f.seek(0)
for i in d:
if i != "line you want to remove...":
f.write(i)
f.truncate()
这个解决方案以读写模式("r+")打开文件,并使用seek重置f指针,然后使用truncate删除最后一次写入之后的所有内容。
f.seek(0)
之后立即使用f.truncate()
,这样如果出现错误,你只会得到一个不完整的文件。但是,真正的解决方案(如果你有足够的硬盘空间)是输出到一个临时文件,然后在一切都成功后使用os.replace()
或pathlib.Path(temp_filename).replace(original_filename)
将其与原始文件交换。 - user3064538i.strip('\n') != "line you want to remove..."
,那就可以完美地解决我的问题。因为仅仅使用 i
对我来说没有任何作用。 - Mangohero1在我看来,最好而且最快的选项是将内容重写到其他地方,而不是将所有内容存储到列表中并重新打开文件进行写入。
with open("yourfile.txt", "r") as file_input:
with open("newfile.txt", "w") as output:
for line in file_input:
if line.strip("\n") != "nickname_to_delete":
output.write(line)
就是这样!只需要一个循环,您就可以完成同样的事情。速度会更快。
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
- shrishindesubprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
- Maxos.replace
(Python 3.3中新增)比调用系统命令mv
更加跨平台。 - 7yl4r$ cat file.txt
1: october rust
2: november rain
3: december snow
这段代码:
#!/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()
if/else
条件语句来判断当前行是否存在字符串在第一遍阅读并在第二遍进行更改(删除特定行)的问题在于,如果文件大小巨大,则会耗尽RAM。相反,更好的方法是逐行阅读,并将它们写入一个单独的文件中,消除您不需要的内容。我已经使用此方法运行过12-50 GB大小的文件,并且RAM使用量几乎保持不变。只有CPU周期显示正在处理。
with open( file_of_nicknames, "r+" ) as f:
lines = f.readlines() # Get a list of all lines
f.seek(0) # Reset the file to the beginning
idx = lines.index("Nickname\n") # Don't forget the '\n'
lines.pop( idx ) # Remove the corresponding index
f.truncate() # Stop processing now
# because len(file_lines) > len( lines )
f.writelines( lines ) # write back
受到先前答案的启发
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
我喜欢这个答案中所解释的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)
也许你已经得到了正确的答案,但这是我的答案。
我不使用列表来收集未经过滤的数据(readlines()
方法所做的),而是使用两个文件。一个用于保存主要数据,另一个用于在删除特定字符串时过滤数据。以下是代码:
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()
我认为如果你将文件读入列表中,然后迭代列表以查找要删除的昵称,则可以更加高效地完成操作。这样做可以避免创建额外的文件,但你需要将结果写回源文件。
以下是我的实现方式:
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()
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()