递归查找并替换文本文件中的字符串
我想要在一个包含子文件夹的目录中,递归地搜索文本文件,并把文件里每次出现的 {$replace}
替换成一个多行字符串的内容。请问我该如何用Python来实现这个功能呢?
到目前为止,我已经有了使用 os.walk
的递归代码,用来获取需要更改的文件列表。
import os
import sys
fileList = []
rootdir = "C:\\test"
for root, subFolders, files in os.walk(rootdir):
if subFolders != ".svn":
for file in files:
fileParts = file.split('.')
if len(fileParts) > 1:
if fileParts[1] == "php":
fileList.append(os.path.join(root,file))
print fileList
10 个回答
15
对于使用Python 3.5+的朋友们,现在可以通过使用glob来递归查找文件,方法是使用**
和recursive
这个标志。
下面是一个例子,展示如何将所有.txt
文件中的hello
替换为world
:
for filepath in glob.iglob('./**/*.txt', recursive=True):
with open(filepath) as file:
s = file.read()
s = s.replace('hello', 'world')
with open(filepath, "w") as file:
file.write(s)
73
os.walk 是个很不错的工具。不过,如果你想要遍历某个文件夹,可能需要过滤一下文件类型(我建议这样做)。为了实现这个,你需要加上 import fnmatch
。
import os, fnmatch
def findReplace(directory, find, replace, filePattern):
for path, dirs, files in os.walk(os.path.abspath(directory)):
for filename in fnmatch.filter(files, filePattern):
filepath = os.path.join(path, filename)
with open(filepath) as f:
s = f.read()
s = s.replace(find, replace)
with open(filepath, "w") as f:
f.write(s)
这样你就可以做一些类似下面的事情:
findReplace("some_dir", "find this", "replace with this", "*.txt")
35
可以看看 os.walk 这个功能:
import os
replacement = """some
multi-line string"""
for dname, dirs, files in os.walk("some_dir"):
for fname in files:
fpath = os.path.join(dname, fname)
with open(fpath) as f:
s = f.read()
s = s.replace("{$replace}", replacement)
with open(fpath, "w") as f:
f.write(s)
上面的解决方案有一些缺点,比如它会打开找到的每一个文件,或者每个文件都会被完全读入内存(如果你有一个1GB的文本文件,那就不好了),但这应该是一个不错的起点。
如果你想做更复杂的查找/替换,而不仅仅是找一个特定的字符串,你可能还想了解一下 re模块。