2011-01-24 56 views
10

我試圖通過讀取每一行來替換文本文件中的文本,對其進行測試,然後在需要更新時進行編寫。我不想保存爲新文件,因爲我的腳本已經先備份文件並在備份上運行。如何按行替換(更新)文件中的文本

這裏是我迄今爲止...我從os.walk(獲得fpath),我保證pathmatch VAR正確返回:

fpath = os.path.join(thisdir, filename) 
with open(fpath, 'r+') as f: 
    for line in f.readlines(): 
     if '<a href="' in line: 
      for test in filelist: 
       pathmatch = file_match(line, test) 
        if pathmatch is not None: 
         repstring = filelist[test] + pathmatch 
         print 'old line:', line 
         line = line.replace(test, repstring) 
         print 'new line:', line 
         f.write(line) 

但是最終情況是,我只得到幾行(正確更新,介意你,但從文件中的前一個重複)更正。我認爲這是一個範圍界定問題,缺點。

*另外:我想知道如何只替換匹配的第一個實例上的文本,例如,我不想匹配顯示文本,只有基礎href。

+1

你有沒有考慮簡單地使用`sed`呢? – Amber 2011-01-24 04:41:24

+0

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – 2011-01-24 04:44:12

+0

@Amber:以某種方式。我真的想完成這個並在稍後學習sed。我幾乎完成了這個... :) – jml 2011-01-24 04:44:17

回答

9

首先,你要寫行是否符合模式。否則,你只寫出匹配的行。其次,在讀取行和寫入結果之間,您需要截斷文件(可以是f.seek(0),然後f.truncate()),或者關閉原始文件並重新打開。採摘前,我想最終是這樣的:

fpath = os.path.join(thisdir, filename) 
with open(fpath, 'r+') as f: 
    lines = f.readlines() 
    f.seek(0) 
    f.truncate() 
    for line in lines: 
     if '<a href="' in line: 
      for test in filelist: 
       pathmatch = file_match(line, test) 
        if pathmatch is not None: 
         repstring = filelist[test] + pathmatch 
         line = line.replace(test, repstring) 
     f.write(line) 
9
  1. 打開讀文件和所有的線複製到內存中。關閉文件。
  2. 對內存中的行應用您的轉換。
  3. 打開文件進行寫入,並寫出內存中的所有文本行。

with open(filename, "r") as f: 
    lines = (line.rstrip() for line in f) 
    altered_lines = [some_func(line) if regex.match(line) else line for line in lines] 
with open(filename, "w") as f: 
    f.write('\n'.join(altered_lines) + '\n') 
1

(相對)安全的方式,以取代在一個文件中的行。

#!/usr/bin/python 
# defensive programming style 
# function to replace a line in a file 
# and not destroy data in case of error 

def replace_line(filepath, oldline, newline): 
    """ 
    replace a line in a temporary file, 
    then copy it over into the 
    original file if everything goes well 

    """ 

# quick parameter checks 
    assert os.exists(filepath)   # ! 
    assert (oldline and str(oldline)) # is not empty and is a string 
    assert (newline and str(newline)) 

    replaced = False 
    written = False 

    try: 

    with open(filepath, 'r+') as f: # open for read/write -- alias to f  

     lines = f.readlines()   # get all lines in file 

     if oldline not in lines: 
      pass       # line not found in file, do nothing 

     else: 
     tmpfile = NamedTemporaryFile(delete=True) # temp file opened for writing 

     for line in lines:   # process each line 
      if line == oldline:  # find the line we want 
      tmpfile.write(newline) # replace it 
      replaced = True 
      else: 
      tmpfile.write(oldline) # write old line unchanged 

     if replaced:     # overwrite the original file  
      f.seek(0)     # beginning of file 
      f.truncate()     # empties out original file 

      for tmplines in tmpfile: 
      f.write(tmplines)   # writes each line to original file 
      written = True 

     tmpfile.close()    # tmpfile auto deleted  
     f.close()       # we opened it , we close it 

    except IOError, ioe:     # if something bad happened. 
    printf ("ERROR" , ioe) 
    f.close()       
    return False 

    return replaced and written  # replacement happened with no errors = True 

(注:這將只替換整個行,所有符合該文件中,該行的)

相關問題