如何使用Python搜索和替换文件中的文本?

Shr*_*ram 179 python string replace file python-3.x

如何使用Python 3搜索和替换文件中的文本?

这是我的代码:

import os
import sys
import fileinput

print ("Text to search for:")
textToSearch = input( "> " )

print ("Text to replace it with:")
textToReplace = input( "> " )

print ("File to perform Search-Replace on:")
fileToSearch  = input( "> " )
#fileToSearch = 'D:\dummy1.txt'

tempFile = open( fileToSearch, 'r+' )

for line in fileinput.input( fileToSearch ):
    if textToSearch in line :
        print('Match Found')
    else:
        print('Match Not Found!!')
    tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()


input( '\n\n Press Enter to exit...' )
Run Code Online (Sandbox Code Playgroud)

输入文件:

嗨,这是abcd,这是abcd

这是虚拟文本文件.

这就是搜索和替换工作方式abcd

当我在上面的输入文件中搜索并替换'abcd'中的'ram'时,它就像魅力一样.但是当我这样做时,反之亦然,即用'ram'代替'abcd',最后会留下一些垃圾字符.

用'ram'代替'abcd'

嗨这是ram嗨这是ram

这是虚拟文本文件.

这就是rambcd的搜索和替换工作方式

Jac*_*ley 277

正如michaelb958所指出的那样,你无法用不同长度的数据替换它,因为这会使其余的部分不合适.我不同意其他海报,建议你从一个文件中读取并写入另一个文件.相反,我会将文件读入内存,修复数据,然后在单独的步骤中将其写入同一文件.

# Read in the file
with open('file.txt', 'r') as file :
  filedata = file.read()

# Replace the target string
filedata = filedata.replace('ram', 'abcd')

# Write the file out again
with open('file.txt', 'w') as file:
  file.write(filedata)
Run Code Online (Sandbox Code Playgroud)

除非你有一个庞大的文件可以使用,它太大而无法一次性加载到内存中.

  • 你是对的,那个 - 伙计 - 是为什么你应该在你自己上网之前测试你的代码;) (30认同)
  • @JonasStein:不,不应该.`with`语句自动关闭语句块末尾的文件. (17认同)
  • `with file = open(..):`是无效的Python(`=`)虽然意图很明确.`.replace()`不修改字符串(它是不可变的)所以你需要使用返回的值.无论如何,支持大文件的代码[可以更简单](http://stackoverflow.com/a/20593644/4279),除非您需要搜索和替换跨越多行的文本. (4认同)
  • @JackAidley因为它简短,易于使用和理解,并且解决了许多人所拥有的真正问题(因此很多人都在寻找 - 从而找到答案). (4认同)
  • @JackAidley很有意思.谢谢你的解释. (2认同)

jfs*_*jfs 210

fileinput已经支持就地编辑.stdout在这种情况下,它重定向到文件:

#!/usr/bin/env python3
import fileinput

with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(text_to_search, replacement_text), end='')
Run Code Online (Sandbox Code Playgroud)

  • `line`已经有了换行符.`end`默认是换行符,`end =''`make`print()`函数不打印额外的换行符 (16认同)
  • 什么是`end =''`参数应该做什么? (12认同)
  • 不要使用fileinput!考虑编写代码来自己做这件事.重定向sys.stdout不是一个好主意,特别是如果你没有尝试这样做..最好像fileinput那样.如果引发异常,您的stdout可能永远不会恢复. (9认同)
  • 如果你真的*想要将stdout重定向到你的文件由于某种原因,它不是比`fileinput`做得更好(基本上,使用`try..finally`或上下文管理器来确保你将stdout设置回它原来的之后的价值).`fileinput`的源代码非常令人难以置信,并且它在一些非常不安全的事情下做了很多.如果它是今天写的,我非常怀疑它会进入stdlib. (5认同)
  • @craigds:错了.`fileinput`不是*all*jobs(*nothing*)的工具,但是在很多情况下****是正确的工具,例如,在Python中实现类似`sed`的过滤器.不要用螺丝刀敲钉子. (4认同)
  • @GuillaumeGendre:rstrip()可能删除太多,例如尾随空格.`end =""`是一个更清洁的解决方案. (3认同)
  • @craigds:我没有看到每次需要时重新完成钻石操作员的好处.不要过早优化.如果你不喜欢这个实施; 提交补丁. (2认同)
  • 对于",end =''"有另一种解决方案.您可以在替换结束时添加.rstrip()以避免双重换行 (2认同)
  • @Ridhuvarshan打开fileinput文档,搜索单词"backup",例如,[点击链接](https://docs.python.org/3/library/fileinput.html)然后按Ctrl + f开始输入单词备份.如果失败了; 问一个单独的Stack Overflow问题. (2认同)
  • 奇怪的是,`fileinput` 改变了 Linux 系统上文件的所有权。例如:如果文件由“X”拥有,并且我以“root”身份运行 python 脚本,则所有权将更改为“root”。 (2认同)

小智 48

正如杰克艾德利发布的那样,JF塞巴斯蒂安指出,这段代码不起作用:

 # Read in the file
filedata = None
with file = open('file.txt', 'r') :
  filedata = file.read()

# Replace the target string
filedata.replace('ram', 'abcd')

# Write the file out again
with file = open('file.txt', 'w') :
  file.write(filedata)`
Run Code Online (Sandbox Code Playgroud)

但是这段代码会起作用(我已经测试过了):

f = open(filein,'r')
filedata = f.read()
f.close()

newdata = filedata.replace("old data","new data")

f = open(fileout,'w')
f.write(newdata)
f.close()
Run Code Online (Sandbox Code Playgroud)

使用此方法,filein和fileout可以是同一个文件,因为Python 3.3将在打开写入时覆盖该文件.

  • 我相信不同之处在于:filedata.replace('ram','abcd')相比较:newdata = filedata.replace("旧数据","新数据")与"with"语句无关 (7认同)
  • 为了挽救其他人重新审视杰克艾德利的答案,自从这个答案以来,它已被纠正,所以这个现在是多余的(并且因为失去了整齐的`with`块而劣质). (7认同)
  • 1.为什么要删除`with`-statement?2.正如我的回答所述,`fileinput`可以在原地工作 - 它可以替换同一文件中的数据(它在内部使用临时文件).不同之处在于`fileinput`不需要将整个文件加载到内存中. (4认同)

Jay*_*ram 43

你可以这样做替换

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
for line in f1:
    f2.write(line.replace('old_text', 'new_text'))
f1.close()
f2.close()
Run Code Online (Sandbox Code Playgroud)


Yuy*_*ina 18

您也可以使用pathlib.

from pathlib2 import Path
path = Path(file_to_search)
text = path.read_text()
text = text.replace(text_to_search, replacement_text)
path.write_text(text)
Run Code Online (Sandbox Code Playgroud)


小智 9

以读取模式打开文件。以字符串格式读取文件。按预期替换文本。关闭文件。再次以写入模式打开文件。最后,将替换的文本写入同一文件。

try:
    with open("file_name", "r+") as text_file:
        texts = text_file.read()
        texts = texts.replace("to_replace", "replace_string")
    with open(file_name, "w") as text_file:
        text_file.write(texts)
except FileNotFoundError as f:
    print("Could not find the file you are trying to read.")
Run Code Online (Sandbox Code Playgroud)


Mis*_*rL2 8

(pip 安装 python-util)

from pyutil import filereplace

filereplace("somefile.txt","abcd","ram")
Run Code Online (Sandbox Code Playgroud)

将所有出现的“abcd”替换为“ram”。
该函数还通过指定支持正则表达式regex=True

from pyutil import filereplace

filereplace("somefile.txt","\\w+","ram",regex=True)
Run Code Online (Sandbox Code Playgroud)

免责声明:我是作者(https://github.com/MisterL2/python-util

  • 我对此有一些不好的经历(它在文件末尾添加了一些字符),所以我不能推荐它,即使一行字会很好。 (2认同)
  • @Azrael3000 它添加了字符?我还没有看到这种情况发生在我身上。如果您在 Github 上提出问题,我将非常感激,以便我可以修复它 https://github.com/MisterL2/python-util (2认同)
  • 感谢您的 github 问题!问题已经解决,现在可以正常工作了。 (2认同)

Ped*_*ito 6

迟到的答案,但这就是我用来在文本文件中查找和替换的内容:

with open("test.txt") as r:
  text = r.read().replace("THIS", "THAT")
with open("test.txt", "w") as w:
  w.write(text)
Run Code Online (Sandbox Code Playgroud)

演示版

  • @HomeroEsmeraldo 这几乎是常识,它超出了这个答案的范围。 (2认同)