2011-01-24 76 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 

(注:这将只替换整个行,所有符合该文件中,该行的)

相关问题