我想循环的内容的文本文件和搜索和替换一些线路,并写入结果回到该文件。我可以第一个载荷整个文件中存储和随后写回,但这可能不是最好的方式来做到这一点。

什么是最好的方式来做到这一点,在下列代码?

f = open(file)
for line in f:
    if line.contains('foo'):
        newline = line.replace('foo', 'bar')
        # how to write this newline back to the file
有帮助吗?

解决方案

我猜测这样的事情应该这样做。它基本上写的内容要一个新的文件并取代了旧的文件的新的文件:

from tempfile import mkstemp
from shutil import move
from os import fdopen, remove

def replace(file_path, pattern, subst):
    #Create temp file
    fh, abs_path = mkstemp()
    with fdopen(fh,'w') as new_file:
        with open(file_path) as old_file:
            for line in old_file:
                new_file.write(line.replace(pattern, subst))
    #Remove original file
    remove(file_path)
    #Move new file
    move(abs_path, file_path)

其他提示

最短路径可能会使用的 fileinput模块.例如,以下增加了行号文件,在地方:

import fileinput

for line in fileinput.input("test.txt", inplace=True):
    print "%d: %s" % (fileinput.filelineno(), line),

这里发生了什么是:

  1. 原始文件移至一个文件备份
  2. 标准输出是重新定向原始文件的内环
  3. 因此,任何 print 发言写信回到原来的文件

fileinput 有更多的花哨。例如,它可用于自动操作上的所有文件 sys.args[1:], 没有你有迭代他们明确。开始Python3.2它还提供了方便的背景下经理使用 with 发言。


同时 fileinput 是伟大的一次性脚本,我将谨慎使用实代码,因为承认这是不是很可读或熟悉的。在实(生产)的代码这是值得花费几个代码行使这一进程明确以及因此使代码的可读性。

有两种选择:

  1. 该文件是不是太大,并且你可以只读它完全存储器。然后关闭文件,重新打开它在编写方式,并编写修改后的内容回。
  2. 文件太大而不能被存储记忆;你可以把它挪到一个临时文件和开放的是,阅读这一行一行写回到原始文件。注意,这需要两倍的储存。

这里是另一个例子,进行了测试,并将符合搜索和替换模式:

import fileinput
import sys

def replaceAll(file,searchExp,replaceExp):
    for line in fileinput.input(file, inplace=1):
        if searchExp in line:
            line = line.replace(searchExp,replaceExp)
        sys.stdout.write(line)

例使用:

replaceAll("/fooBar.txt","Hello\sWorld!$","Goodbye\sWorld.")

这个应该的工作:(就地编辑)

import fileinput

# Does a list of files, and
# redirects STDOUT to the file in question
for line in fileinput.input(files, inplace = 1): 
      print line.replace("foo", "bar"),

基于答案由托马斯*Watnedal.然而,这并不是答案的线路的部分原来的问题。的功能仍然可以取代上一线的基础上

这实施替换的文件的内容,而不使用临时文件,作为结果文件的权限保持不变。

还重。子,而不是替代,可以允许regex替换,而不是普通的文本替换只。

阅读该文件作为一个单一串而不是逐行许多行匹配和更换。

import re

def replace(file, pattern, subst):
    # Read contents from file as a single string
    file_handle = open(file, 'r')
    file_string = file_handle.read()
    file_handle.close()

    # Use RE package to allow for replacement (also allowing for (multiline) REGEX)
    file_string = (re.sub(pattern, subst, file_string))

    # Write contents to file.
    # Using mode 'w' truncates the file.
    file_handle = open(file, 'w')
    file_handle.write(file_string)
    file_handle.close()

作为lassevk表明,写出新的文件作为你走,这里是一些例编码:

fin = open("a.txt")
fout = open("b.txt", "wt")
for line in fin:
    fout.write( line.replace('foo', 'bar') )
fin.close()
fout.close()

如果你想要一个通用功能来代替 任何 案文与其他一些文字,这可能是最好的路要走,特别是如果你的粉丝regex:

import re
def replace( filePath, text, subs, flags=0 ):
    with open( filePath, "r+" ) as file:
        fileContents = file.read()
        textPattern = re.compile( re.escape( text ), flags )
        fileContents = textPattern.sub( subs, fileContents )
        file.seek( 0 )
        file.truncate()
        file.write( fileContents )

一个多功能已大大增强的办法是使用环境管理等的代码如下:

from tempfile import mkstemp
from shutil import move
from os import remove

def replace(source_file_path, pattern, substring):
    fh, target_file_path = mkstemp()
    with open(target_file_path, 'w') as target_file:
        with open(source_file_path, 'r') as source_file:
            for line in source_file:
                target_file.write(line.replace(pattern, substring))
    remove(source_file_path)
    move(target_file_path, source_file_path)

你可以找到充分段 在这里,.

创建一个新的文件复制线,从古到新的和更换之前编写的行为的新的文件。

扩大对@基兰的答案,我同意是更为简洁的和功能已大大增强,这增加了解码器支持的阅读和写作的UTF-8:

import codecs 

from tempfile import mkstemp
from shutil import move
from os import remove


def replace(source_file_path, pattern, substring):
    fh, target_file_path = mkstemp()

    with codecs.open(target_file_path, 'w', 'utf-8') as target_file:
        with codecs.open(source_file_path, 'r', 'utf-8') as source_file:
            for line in source_file:
                target_file.write(line.replace(pattern, substring))
    remove(source_file_path)
    move(target_file_path, source_file_path)

使用hamishmcn的回答作为一个模板,我能够搜索线在一个文件,该文件符合我regex和替换空串。

import re 

fin = open("in.txt", 'r') # in file
fout = open("out.txt", 'w') # out file
for line in fin:
    p = re.compile('[-][0-9]*[.][0-9]*[,]|[-][0-9]*[,]') # pattern
    newline = p.sub('',line) # replace matching strings with empty string
    print newline
    fout.write(newline)
fin.close()
fout.close()

如果删除缩进在如下面将搜索和替换在多个行。见下文的例子。

def replace(file, pattern, subst):
    #Create temp file
    fh, abs_path = mkstemp()
    print fh, abs_path
    new_file = open(abs_path,'w')
    old_file = open(file)
    for line in old_file:
        new_file.write(line.replace(pattern, subst))
    #close temp file
    new_file.close()
    close(fh)
    old_file.close()
    #Remove original file
    remove(file)
    #Move new file
    move(abs_path, file)

Linux用户:

import os
os.system('sed -i \'s/foo/bar/\' '+file_path)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top