2015-04-03 99 views
1

我試圖刪除38行文本,在Python中的.txt文件中遇到特定短語,同時仍然打印文本的其餘部分。不識別Python中的循環變量

我目前擁有的代碼是

with open('text_file.txt','r') as f: 
lines = f.readlines() 
for line in lines: 
    if "certain_phrase" in line: 
     for num in range(38): 
      del line 
    else: 
     print(line,end='') 

不過,我不斷收到以下錯誤:

Traceback (most recent call last): 
    File "C:\<location of file>\python_program.py", line 6, in <module> 
    del line 
NameError: name 'line' is not defined 

沒有人有任何建議或線索,爲什麼它不能識別「行」一旦我把它放在下面的for循環裏面?另外,有沒有更好的方法來執行這種程序?

+2

即使沒有錯誤,此代碼也不會執行你想要的操作 – 2015-04-03 15:09:20

+0

它不知道變量'line'在你的'for循環中num的第二次迭代,因爲你剛刪除它在以前的迭代中並沒有在 – 2015-04-03 15:11:05

+0

之間重新定義它首先建議:讀取文件時不需要第2行(由於將整個文件存儲在內存中,而不是逐行讀取,這會浪費內存)=>在f' – 2015-04-03 15:15:52

回答

3

您將需要從列表中刪除,你不能del行了,最簡單的方法是寫一個臨時文件,如果要修改的文件複製後,如果您只想打印無視38符合打印代替寫:

with open('in.txt','r') as f,open('temp.txt','w') as temp: 
    for line in f: 
     if "phrase" in line: 
      for i in range(38): 
       next(f) # skip 38 lines 
     else: 
      temp.write(line) 

然後使用shutil移動文件:

import shutil 

shutil.move("temp.txt","in.txt") 

你也可以使用一個NamedTemporaryFile

from tempfile import NamedTemporaryFile 

with open('file.txt','r') as f, NamedTemporaryFile(dir=".",delete=False) as temp: 
    for line in f: 
     if "phrase" in line: 
      for i in range(38): 
       next(f) 
     else: 
      temp.write(line) 

import shutil 
shutil.move(temp.name,"file.txt") 

我看到的唯一潛在的問題是,如果這句話是在38線被忽略的一個,你也應該從那裏取出接下來的38行。

To ignore until a second phrase, keep looping in the inner loop until you find the second phrase then break: 

with open('in.txt','r') as f, NamedTemporaryFile(dir=".", delete=False) as temp: 
    for line in f: 
     if "phrase" in line: 
      for _line in f: 
       if "phrase2" in _line: 
        break 
     else: 
      temp.write(line) 
+0

這工作非常好!非常感謝!非常有用的知道! – codycrossley 2015-04-03 15:34:30

+0

@codycrossley,不用擔心,不客氣。 – 2015-04-03 15:35:12

+0

難道你不能使用while循環,並重置計數器,如果該短語是在38忽略行? – 2015-04-03 15:39:49

0

del line實際上刪除了變量line,這意味着當您第二次嘗試時,它不起作用,因爲line不再被定義。您可以遍歷索引來查找線,突破,然後刪除下一個38行:

with open('text_file.txt','r') as f: 
lines = f.readlines() 
for i in range(len(lines)): 
    if "certain_phrase" in lines[i]: 
     break 
    else: 
     print(line,end='') 
for num in range(38): 
    del lines[i] 
0
​​
+0

我很確定這不會執行提問者想要的操作......這會刪除包含「certain_phrase」的前38行,而不是直到它在一行中找到「certain_phrase」,然後刪除(或真正跳過)接下來的38行 – Foon 2015-04-03 17:01:37

+0

@Foon是的,我誤解了這個問題。固定。 – Alan 2015-04-03 17:54:51

1

,而不是試圖從文件中刪除線,編寫基於舊的一個新文件。以下使用__next__()跳過發生器產生的line

with open('text_file.txt','r') as f, open('text_file_mod.txt', 'w') as w: 
    for line in f: 
     w.write(line) 
     if "certain_phrase" in line: 
      for num in range(38): # skip 38 lines 
       next(f) 

如果你從交互式解釋這樣做,可以防止它通過next(f)w.write(line)結果保存到變量吐出返回的值。