Replace strings in files by Python, recursively in given directory and its subdirectories?(是否在给定目录及其子目录中递归地用Python替换文件中的字符串?)
问题描述
如何在给定目录及其子目录内递归地将文件内的字符串匹配替换为给定的替换?
伪码:
import os
import re
from os.path import walk
for root, dirs, files in os.walk("/home/noa/Desktop/codes"):
for name in dirs:
re.search("dbname=noa user=noa", "dbname=masi user=masi")
// I am trying to replace here a given match in a file
推荐答案
将所有这些代码放入名为mass_replace
的文件中。在Linux或MacOSX上,您可以执行chmod +x mass_replace
,然后只需运行以下命令。在Windows下,您可以使用python mass_replace
后跟适当的参数来运行它。
#!/usr/bin/python
import os
import re
import sys
# list of extensions to replace
DEFAULT_REPLACE_EXTENSIONS = None
# example: uncomment next line to only replace *.c, *.h, and/or *.txt
# DEFAULT_REPLACE_EXTENSIONS = (".c", ".h", ".txt")
def try_to_replace(fname, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
if replace_extensions:
return fname.lower().endswith(replace_extensions)
return True
def file_replace(fname, pat, s_after):
# first, see if the pattern is even in the file.
with open(fname) as f:
if not any(re.search(pat, line) for line in f):
return # pattern does not occur in file so we are done.
# pattern is in the file, so perform replace operation.
with open(fname) as f:
out_fname = fname + ".tmp"
out = open(out_fname, "w")
for line in f:
out.write(re.sub(pat, s_after, line))
out.close()
os.rename(out_fname, fname)
def mass_replace(dir_name, s_before, s_after, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
pat = re.compile(s_before)
for dirpath, dirnames, filenames in os.walk(dir_name):
for fname in filenames:
if try_to_replace(fname, replace_extensions):
fullname = os.path.join(dirpath, fname)
file_replace(fullname, pat, s_after)
if len(sys.argv) != 4:
u = "Usage: mass_replace <dir_name> <string_before> <string_after>
"
sys.stderr.write(u)
sys.exit(1)
mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])
编辑:我已将上述代码从原始答案更改。有几个变化。首先,mass_replace()
现在调用re.compile()
预编译搜索模式;其次,为了检查文件的扩展名是什么,我们现在向.endswith()
传递文件扩展名元组,而不是调用.endswith()
三次;第三,它现在使用最新版本的Python中提供的with
语句;最后,file_replace()
现在检查是否在文件中找到该模式,如果(旧版本会重写每个文件,即使输出文件与输入文件相同也会更改时间戳;这很不雅观。)
edit:我将其更改为默认替换每个文件,但是您可以使用一行代码进行编辑,以将其限制为特定的扩展名。我认为替换每个文件是更有用的开箱即用的默认设置。可以使用不接触的扩展名或文件名列表、不区分大小写的选项等对其进行扩展。
编辑:@asciimo在评论中指出了一个错误。我对此进行了编辑以修复错误。str.endswith()
记录为接受要尝试的字符串元组,但不接受列表。已修复。另外,我让两个函数接受一个可选参数,以允许您传入一个扩展元组;修改此参数以接受命令行参数以指定哪些扩展应该非常容易。
这篇关于是否在给定目录及其子目录中递归地用Python替换文件中的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:是否在给定目录及其子目录中递归地用Python替换文件中的字符串?
基础教程推荐
- 使用Python匹配Stata加权xtil命令的确定方法? 2022-01-01
- 如何在Python中绘制多元函数? 2022-01-01
- 将 YAML 文件转换为 python dict 2022-01-01
- 如何在 Python 中检测文件是否为二进制(非文本)文 2022-01-01
- Python 的 List 是如何实现的? 2022-01-01
- 使用 Google App Engine (Python) 将文件上传到 Google Cloud Storage 2022-01-01
- 症状类型错误:无法确定关系的真值 2022-01-01
- 哪些 Python 包提供独立的事件系统? 2022-01-01
- 使 Python 脚本在 Windows 上运行而不指定“.py";延期 2022-01-01
- 合并具有多索引的两个数据帧 2022-01-01