Python 删除文件中的行
我想在一个文件中显示行,让用户决定删除哪一行,然后将所有行写回文件,除了用户想要删除的那一行 这是我目前为止尝试过的,但我有点卡住了Python 删除文件中的行,python,Python,我想在一个文件中显示行,让用户决定删除哪一行,然后将所有行写回文件,除了用户想要删除的那一行 这是我目前为止尝试过的,但我有点卡住了 def delete_result(): text_file = open('minigolf.txt', 'r') zork = 0 for line in text_file: zork = zork + 1 print zork, line delete_player = raw_input
def delete_result():
text_file = open('minigolf.txt', 'r')
zork = 0
for line in text_file:
zork = zork + 1
print zork, line
delete_player = raw_input ("Who's result do you want to delete?")
text_file.close()
或
minigolf.txt包含:
Sara;37;32;47;
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
如果你用名字;试试看:
file = open("foo.txt")
cont = file.read()
cont = cont.splitlines()
line_number = 0
name = "Johan"
for i in cont:
if i.startswith(name):
line_number = cont.index(i)
cont.pop(line_number)
file.close()
file = open("foo.txt", "w")
cont= "\n".join(cont)
file.write(cont)
file.close()
这将解决您的问题,并为您提供一种更稳健的方式来处理用户输入:
def delete_result():
with open('minigolf.txt', 'r') as f:
text_file = f.readlines()
# find newline char and strip from endings
if '\r' in text_file[0]:
if '\n' in text_file[0]:
newline = '\r\n'
else:
newline = '\r'
else:
newline = '\n'
text_file = [t[:-len(newline)]
if t[-len(newline):] == newline
else t for t in text_file]
users = set()
for line_number, line in enumerate(text_file):
print line_number + 1, line
users.add(line[:line.index(';')].lower())
# get result from user with exception handling
result = None
while not result:
delete_player = raw_input('Which user do you want to delete? ')
try:
result = str(delete_player).lower()
assert result in users
except ValueError:
print('Sorry, I couldn\'t parse that user.')
except AssertionError:
print('Sorry, I couldn\'t find that user.')
result = None
# write new file
new_file = [t + newline for t in text_file
if t[:t.index(';')].lower() != result]
with open('minigolf.txt', 'w') as f:
f.writelines(new_file)
if __name__ == '__main__':
delete_result()
编辑:我看到您想按名称而不是行号删除,所以将其更改为类似于@danidee的方法。为了清晰起见,对danidee的答案进行了轻微修改
def delete_result():
with open('minigolf.txt', 'r') as f:
results = f.readlines()
print(results)
user = raw_input('which user do you want to delete')
for res in results:
if user.lower() in res: # assumption that sara == Sara
results.remove(res)
with open('minigolf.txt', 'w') as f:
f.writelines(results)
return 'user was found and removed'
return 'user was not found'
def delete_result():
with open('minigolf.txt', 'r') as f:
results = f.readlines()
print "\n".join(results)
delete_player = raw_input ("Who's result do you want to delete?")
deleted = False
for res in results:
if delete_player.lower() in res.lower():
results.remove(res)
with open('minigolf.txt', 'w') as f:
f.writelines(results)
print "User was found and removed"
deleted = True
# for
if not deleted:
print "User not found..."
# def
结果:
>> python delete_user.py
Sara;37;32;47;
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
Who's result do you want to delete?sara
User was found and removed
>> cat minigolf.txt
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
>> python delete_user.py
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
Who's result do you want to delete?nonuser
User not found...
所有其他答案都是有效的,因此您可能对如何加载文件、更改内容然后将文件保存回去有了很好的了解 我只想指出,有可能直接在存储内存中更改文件的内容。这样做并不总是明智的,它有它的缺点,但因为它可能对未来的一些用途有用 要将内容更改(删除或插入)到现有文件中,可以使用mmap模块 它允许您映射RAM或存储内存(文件)的一部分,并像字符串一样访问和编辑它。也许是一份更好的清单 因此,要删除要删除的行,请打开文件,加载其内容并执行find()或其他操作,以查找要删除的行的索引及其长度 然后,您可以对文件进行内存映射,只需将其余内容沿着要删除的行向上移动,从而“覆盖”不需要的行。你可以用切片来做。然后调整内存映射的大小,以在移动内容后切断剩余的字节。因此,您可以将文件大小调整到合适的大小,然后可以关闭不会关闭文件的mmap 您可以以这种方式在文件中插入一行。首先调整文件的大小,将内容移到末尾,以留出一个显示行的空间,然后再将其写入 这听起来有点复杂,而且工作量很大,但实际上不是。这样就省去了每次删除该行时编写整个文件的麻烦 我没有检查它有多快,是否比每次覆盖都快。但这是一个我觉得值得一提的解决方案 下面是一些快速组装的代码:
# This needs checks and rechecks
# Also, its efficiency is questionable. Some optimization can be done with find() and rfind()
# But we can choose to believe in the module and just do it.
# The nice thing is that we can use find() to point the user, not searching for the line number like mad.
from mmap import mmap
def removeline (fname, nl):
f = open(fname, "rb+")
m = mmap(f.fileno(), 0)
size = m.size()
ixl = 0 # Index of line to delete
nle = 0 # Count new lines found
# Find the line:
while nle!=nl:
# Suppose we know our EOL will always be \n
i = m.find("\n", ixl)
if i==-1: break
ixl = i+1
nle += 1
if ixl>=size: f.close(); return # nl is greater than number of lines in the f
ixle = m.find("\n", ixl) # Index of end of that line
ixle = (ixle+1, None)[ixle==-1] #Either include the EOL in deletion or delete to the EOF
# Line length:
if ixle!=None: ll = ixle-ixl
else:
# Remove from ixl to the end of file.
# I.e. just shrink the file.
ns = size-(size-ixl)
if ns==0:
# Delete all
m.close()
f.close()
f = open(fname, "wb")
f.close()
return
m.resize(ns) # Cut off the rubbish
m.close(); f.close()
return
# Shift the rest over the offending line:
try: m[ixl:size-ll] = m[ixle:size]
except:
m.close()
f.close()
raise
ns = size-ll
if ns==0:
# Delete all - mmap doesn't like to resize to 0 bytes., hm, perhaps f.truncate()
m.close()
f.close()
f = open(fname, "wb")
f.close()
return
m.resize(ns) # Cut off the rubbish
m.close()
f.close()
您是否尝试使用用户名或行号删除?如果用户想要删除第5行和第10行,删除第5行是否会改变第10行是什么,或者您是否必须基本上重写文件,而不包含他们想要删除的行?@depperm基本上重写文件,而不包含他们想要删除的行请注意,您不应该使用
readlines
或writelines
如果你有一个巨大的txt文件要读,或者有很多项目要写入文件,你最好循环阅读它们,然后一次一个地写/读这些项目。。稍微修改了答案并贴在下面。。!EOL可以是\n、\r或\r\n,具体取决于生成该文件的操作系统的约定和/或编辑器。所以最好使用line.rstrip(“\n”).rstrip(“\r”),或者将整个文件加载到RAM中,然后再加载content.splitlines(),不用担心EOL。另外,如果剥离readline()/readlines(),则文件对象包含一个名为newlines的属性,该属性应包含OS有效的NL分隔符。@Dalen这是一个很好的观点,唯一的问题是知道要重新添加哪些换行符(我想,如果新文件是逐行写入的,这不会引起关注)。谢谢你的建议!也许从first readline()获取EOL,并将其作为我们的人完成整个文件。然后以任何适合需要的方式处理其余部分。只是个想法,有道理。。渴望看到一个代码示例。。谢谢分享!我添加了代码示例。有点笨重。小心使用。
>> python delete_user.py
Sara;37;32;47;
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
Who's result do you want to delete?sara
User was found and removed
>> cat minigolf.txt
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
>> python delete_user.py
Johan;44;29;34;
Kalle;33;34;34;
Oskar;23;47;45;
Who's result do you want to delete?nonuser
User not found...
# This needs checks and rechecks
# Also, its efficiency is questionable. Some optimization can be done with find() and rfind()
# But we can choose to believe in the module and just do it.
# The nice thing is that we can use find() to point the user, not searching for the line number like mad.
from mmap import mmap
def removeline (fname, nl):
f = open(fname, "rb+")
m = mmap(f.fileno(), 0)
size = m.size()
ixl = 0 # Index of line to delete
nle = 0 # Count new lines found
# Find the line:
while nle!=nl:
# Suppose we know our EOL will always be \n
i = m.find("\n", ixl)
if i==-1: break
ixl = i+1
nle += 1
if ixl>=size: f.close(); return # nl is greater than number of lines in the f
ixle = m.find("\n", ixl) # Index of end of that line
ixle = (ixle+1, None)[ixle==-1] #Either include the EOL in deletion or delete to the EOF
# Line length:
if ixle!=None: ll = ixle-ixl
else:
# Remove from ixl to the end of file.
# I.e. just shrink the file.
ns = size-(size-ixl)
if ns==0:
# Delete all
m.close()
f.close()
f = open(fname, "wb")
f.close()
return
m.resize(ns) # Cut off the rubbish
m.close(); f.close()
return
# Shift the rest over the offending line:
try: m[ixl:size-ll] = m[ixle:size]
except:
m.close()
f.close()
raise
ns = size-ll
if ns==0:
# Delete all - mmap doesn't like to resize to 0 bytes., hm, perhaps f.truncate()
m.close()
f.close()
f = open(fname, "wb")
f.close()
return
m.resize(ns) # Cut off the rubbish
m.close()
f.close()