Python在文件中替换字符串,未更改则不触碰文件
如果在Python中使用字符串的replace方法,但没有进行任何替换,它会返回什么?另外,使用Python的file.open(f, 'w')时,即使没有做任何更改,文件也会被更新吗?
我在用Python尝试把一组文件中的'oldtext'替换成'newtext'。如果文件里有'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。
相关问题:
3 个回答
你的情况是一个特殊的例子:'newtext' 和 'oldtext' 的字符数是完全相同的。
因此,可以使用以下代码之一,准确地将一个单词'oldtext'或包含这个单词的整行,替换为'newtext'或包含'newtext'的整行。
.
如果文件的大小不是特别大,可以将每个文件的内容全部读入内存:
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
.
这些程序做的事情是最基本的,所以我认为它们的速度很快。
.
注意:以模式 'rb+' 打开的文件,如果没有进行任何修改,其最后修改时间不会改变。
如果在Python中使用字符串的.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)
如果Python的字符串替换(string.replace)没有进行任何替换,它会返回什么?
它会返回原来的字符串。
Python的文件打开(file.open(f, 'w'))即使没有做任何更改,也总是会触碰到文件吗?
不仅仅是触碰文件,它还会删除文件中原本的内容。
所以,你可以通过检查 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