2016-07-18 31 views
3

我想在文件中显示行,让用户决定删除哪行,然后将所有行写回文件,用户想要删除的行除外。删除文件中的行

这是我到目前为止所尝试的,但我有点卡住了。

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

def delete_result(): 
    text_file = open('minigolf.txt', 'r') 
    for line in text_file: 
     if ';' in line: 
      line2 = line.split(";") 
     print line2 
    print "***" 
    delete = 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; 
+0

你想删除的用户名或行号? – danidee

+0

如果用户想要删除第5行和第10行删除5更改第10行是什么,或者您将不得不基本重写该文件而不删除他们想要删除的行? – depperm

+0

@danidee用户名 –

回答

0

这将解决您的问题,给你的处理用户输入一个更强大的方式:

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的方法。

+1

EOL可以是\ n,\ r或\ r \ n,具体取决于操作系统的惯例和/或生成该文件的编辑器。所以最好使用line.rstrip(“\ n”).rstrip(“\ r”),或者将整个文件加载到RAM中,然后加载content.splitlines(),而不用担心EOL。此外,如果剥离readline()/ readlines()结果,则该文件对象包含一个称为换行符的属性,该属性应包含OS有效的NL分隔符。 – Dalen

+0

@Dalen这是一个很好的观点,唯一的问题是要知道哪些新行添加回去(如果新文件是逐行写入的,我不会担心)。感谢您的建议! – Alec

+1

也许从第一个readline()中得到EOL,并把它作为我们的整个文件。然后以任何适合需求的方式处理其余部分。只是一个想法。 – Dalen

1
line_number = 5 #for example 
file = open("foo.txt") 
cont = file.read() 
cont = cont.splitlines() 

cont.pop(line_number-1) 
file.close() 
file = open("foo.txt", "w") 
cont= "\n".join(cont) 
file.write(cont) 
file.close() 

如果用名字做;尝试:

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() 
+0

我写的第二个代码是你想要的东西... –

1
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' 
+1

请注意,如果您需要读取大量的txt文件或者需要写入大量文件,则不应该使用'readlines'或'writelines',最好是循环读写这些文件并在其中写入/读取一次 – danidee

+0

不错的做法先生..稍微修改了答案,并张贴在下面..! –

1

少许修改danidee的答案清晰

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... 
2

所有其他的答案是有效的,所以你可能得到关于如何通过加载到去做一个好主意该文件,更改内容,然后将文件保存回来。

我只想指出,有可能直接在存储器中更改文件的内容。这样做并不总是明智的,这个东西有其缺点,但它对于未来的某些用途可能是有用的。

要将内容更改(删除或插入)到现有文件中,您可以使用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() 

+0

有道理..渴望看到一个代码示例..感谢分享! –

+0

我添加了代码示例。这有点笨重。谨慎使用。 – Dalen