2016-07-18 91 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