如果没有替换,Python字符串替换文件而不触及文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果没有替换,Python字符串替换文件而不触及文件相关的知识,希望对你有一定的参考价值。

如果没有进行字符串替换,Python的string.replace会返回什么?即使没有进行任何更改,Python的file.open(f,'w')是否始终触摸该文件?

使用Python,我试图在一组文件中用'newtext'替换'oldtext'的出现。如果文件包含'oldtext',我想进行替换并保存文件。否则,什么也不做,所以文件保持旧的时间戳。

以下代码工作正常,除非所有文件都被写入,即使没有进行字符串替换,并且所有文件都有新的时间戳。

for match in all_files('*.html', '.'):  # all_files returns all html files in current directory     
  thefile = open(match)
  content = thefile.read()              # read entire file into memory
  thefile.close()
  thefile = open(match, 'w')             
  thefile.write(content.replace(oldtext, newtext))  # write the file with the text substitution
  thefile.close()

在这段代码中,我只是在发生字符串替换时尝试执行file.write,但是,所有文件都获得了新的时间戳:

count = 0
for match in all_files('*.html', '.'):       # all_files returns all html files in current directory
    thefile = open(match)
    content = thefile.read()                 # read entire file into memory
    thefile.close()
    thefile = open(match, 'w')
    replacedText = content.replace(oldtext, newtext) 
    if replacedText != '':
        count += 1
        thefile.write(replacedText)
    thefile.close()
print (count)        # print the number of files that we modified

最后,count是文件总数,而不是修改的文件数。有什么建议?谢谢。

我在Windows上使用Python 3.1.2。

答案

如果没有进行字符串替换,Python的string.replace会返回什么?

它返回原始字符串。

即使没有进行任何更改,Python的file.open(f,'w')是否始终触摸该文件?

它不仅仅是触摸文件,还会破坏f用来包含的任何内容。

因此,您可以测试文件是否需要使用if replacedText != content重写,并且只有在这种情况下才会以写入模式打开文件:

count = 0
for match in all_files('*.html', '.'):       # all_files returns all html files in current directory
    with open(match) as thefile:
        content = thefile.read()                 # read entire file into memory
        replacedText = content.replace(oldtext, newtext)
    if replacedText!=content:
        with open(match, 'w') as thefile:
            count += 1
            thefile.write(replacedText)
print (count)        # print the number of files that we modified
另一答案

如果没有进行字符串替换,Python的string.replace会返回什么?

如果对象是字符串的子类,str.replace()返回字符串本身或副本。

即使没有进行任何更改,Python的file.open(f,'w')是否始终触摸该文件?

open(f, 'w')打开并截断文件f

请注意以下代码是CPython特定的;它在pypy,jython上无法正常工作:

count = 0
for match in all_files('*.html', '.'):
    content = open(match).read()
    replacedText = content.replace(oldtext, newtext) 
    if replacedText is not content:
       count += 1
       open(match, 'w').write(replacedText)
print (count)   
另一答案

您的案例是一个特例:'newtext'与'oldtext'具有完全相同的字符数。

因此,可以使用以下代码之一来准确地替换单词'oldtext'或单词'oldtext'所在的行,单词'newtext'或'newtext'替换'oldtext'的行。

.

如果文件的大小不是超大,则每个文件的内容可以完全读入内存:

from os import fsync      # code using find()

count = 0
for match in all_files('*.html', '.'):
    with open(match,'rb+') as thefile:
        diag = False
        fno = thefile.fileno()
        content = thefile.read()
        thefile.seek(0,0)
        x = content.find('oldtext')
        while x>=0:
            diag = True
            thefile.seek(x,1)
            thefile.write('newtext')
            thefile.flush()
            fsync(fno)
            x = content[thefile.tell():].find('oldtext')
    if diag:
        cnt += 1

要么

from os import fsync     # code using a regex
import re
pat = re.compile('oldtext')

count = 0
for match in all_files('*.html', '.'):
    with open(match,'rb+') as thefile:
        diag = False
        fno = thefile.fileno()
        content = thefile.read()
        thefile.seek(0,0)
        prec = 0
        for mat in pat.finditer(content):
            diag = True
            thefile.seek(mat.start()-prec,1)
            thefile.write('newtext')
            thefile.flush()
            fsync(fno)
            prec = mat.end()
    if diag:
        cnt += 1

.

对于繁重的文件,可以在线后读取和重写:

from os import fsync   # code for big files, using regex
import re
pat = re.compile('oldtext')

count = 0
for match in all_files('*.html', '.'):
    with open(match,'rb+') as thefile:
        diag = False
        fno = thefile.fileno()
        line = thefile.readline()
        while line:
            if 'oldtext' in line:
                diag = True
                thefile.seek(-len(line),1)
                thefile.write(pat.sub('newtext',line))
                thefile.flush()
                fsync(fno) 
            line = thefile.readline()
    if diag:
        cnt += 1

.

每次编写后都需要使用thefile.flush()fsync(fno)指令,以便文件处理程序thefile随时准确指出文件中的确切位置。他们允许通过设置write()获得有效的写作

flush()不一定将文件的数据写入磁盘。使用flush()后跟os.fsync()来确保此行为。 http://docs.python.org/library/stdtypes.html#file.flush

.

这些程序做得最少。所以我认为他们很快。

.

Nota bene:如果没有执行任何修改,以'rb+'模式打开的文件不会更改其上次修改的时间。

以上是关于如果没有替换,Python字符串替换文件而不触及文件的主要内容,如果未能解决你的问题,请参考以下文章

渲染JSON而不替换Jinja中的字符[重复]

python查找文本文档中特定间隔位置的字符并替换

Python 没有替换 % 符号

批量替换字符串的python实现

python 文件操作 替换性修改文件内容

替换字符串中的单词而不跳过空格