你怎么能更换比赛用在给定的目录及其子目录递归给定替换?
伪代码
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或Mac OS X,你可以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>\n"
sys.stderr.write(u)
sys.exit(1)
mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])
编辑:我已经从原来的回答改变了上面的代码。 有几个变化。 首先, mass_replace()
现在调用re.compile()
预编译搜索模式; 第二,要检查该文件有什么扩展,现在我们传递的文件扩展名的元组.endswith()
而不是调用.endswith()
三次; 第三,它现在使用with
在最新版本的Python提供说明; 最后, file_replace()
现在检查,看是否图形文件中找到,并且不重写该文件,如果没有找到该模式。 (旧版本将重写每一个文件,改变即使输出文件是相同的输入文件中的时间戳;这是不雅观。)
编辑:我改变了这种默认为替换每个文件,但有一条线,你可以编辑将其限制在特定的扩展。 我想替换每个文件是一个更加有用外的开箱默认。 这可以通过扩展或文件名不要触摸列表进行扩展,选项,使其不区分大小写,等等。
编辑:在评论,@asciimo指出的错误。 我编辑此修复bug。 str.endswith()
是记录接受字符串的元组的尝试,但不是列表。 固定。 另外,我做了一对夫妇的函数接受一个可选的参数,让你在扩展的元组通过; 它应该是很容易修改此接受命令行参数来指定哪些扩展。
你真的需要正则表达式?
import os
def recursive_replace( root, pattern, replace )
for dir, subdirs, names in os.walk( root ):
for name in names:
path = os.path.join( dir, name )
text = open( path ).read()
if pattern in text:
open( path, 'w' ).write( text.replace( pattern, replace ) )
当然,如果你只是想获得它无需编码起来做,使用查找和xargs的:
find /home/noa/Desktop/codes -type f -print0 | \
xargs -0 sed --in-place "s/dbname=noa user=noa/dbname=masi user=masi"
(你可以有可能与发现的-exec什么也这么做,但我更喜欢xargs的。)
这就是我如何才能找到和使用python的文件替换字符串。 这是一个简单的小功能,将递归搜索目录中的字符串,并用字符串替换它。 您还可以限制文件与特定文件扩展名像下面的例子。
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")
这应该工作:
import re, os
import fnmatch
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("namelist.wps", 'a') as out:
with open("namelist.wps", 'r') as readf:
for line in readf:
line = re.sub(r"dbname=noa user=noa", "dbname=masi user=masi", line)
out.write(line)