我找不到一个问题的问题。
我用来bash中的脚本,但是我注意到bash在大型操作方面的效率过高,所以我在Python中重写了我的代码。
但是我在python中菜鸟!所以我经常谷歌,但在这里我有问题...我的Bash脚本中有很多SED操作,我想知道重新创建此问题的方法(这将是Python重写所有SED操作的起点):
sed -i -e "s/(log_min_messages = ).*/1notice/" "/opt/PostgreSQL/9.6/data/postgresql.conf"
在该文件中替换" log_min_messages"之后的所有内容。
基本上,打开postgresql.conf文件,搜索匹配的模式" log_min_messages = *"(其中 *指示它在'='='='=')之后无关紧要,然后用字符串'通知'替换' *' *' *' *' *' *' *' *' *' *'>
示例:
之前log_min_messages = something
在该sed命令之后:
log_min_messages = notice
我想知道我是否必须使用" re"?
编辑:一个想法是在python脚本中实现perl命令,因此,如果有人知道如何在perl中做到这一点,那将是一个很好的答案
configparser可以读取/写入ini配置文件。
我不确定它是否满足您的要求。
参考:https://docs.python.org/2/library/configparser.html
第一步是从文件中读取配置,然后更改配置值中的值,终于将配置写回文件。
hm ... sed更简单..:)
根据Alex Martelli的解决方案放置解决方案
如果我们有这样的test2.cfg:
key1=abcd
key2=abcd3
然后使用下面的代码:
import ConfigParser
class FakeHeader(object):
def __init__(self, fp, section='zconfig'):
self.section = '[%s]n' % section
self.fp = fp
def readline(self):
if self.section:
try:
return self.section
finally:
self.section = None
else:
return self.fp.readline()
class ZConfigParser(ConfigParser.ConfigParser, object):
def __init__(self, default_section='zconfig'):
ConfigParser.ConfigParser.__init__(self)
self.default_section = default_section
def read(self, fp):
new_fp = FakeHeader(open(fp), self.default_section)
return super(ZConfigParser, self).readfp(new_fp)
def write(self, fp):
fp = open(fp, "w")
for (key, value) in self.items(self.default_section):
fp.write("%s = %sn" % (key, str(value).replace('n', 'nt')))
fp.write("n")
def get(self, key):
return super(ZConfigParser, self).get(self.default_section, key)
def set(self, key, value):
super(ZConfigParser, self).set(self.default_section, key, value)
# here you can use it to read/write a configure file without section in somehow graceful method.
zconfig = ZConfigParser()
# read file
zconfig.read("test2.cfg")
print zconfig.get('key1')
zconfig.set('key1', 'alfasjdlfabalalla')
# then you can check test3.cfg which key1=alfasjdlfabalalla
zconfig.write('test3.cfg')
希望它能为您提供帮助。
sed
的转换非常简单,我们必须创建一个临时文件(outfname
)才能写入新文本,然后将其重命名。Python正则表达式(如Perl)被扩展,因此括号不会被逃脱。
字符串r"..."
上的领先r
是一个原始字符串,这意味着它不会尝试翻译诸如1
的逃逸字符。
import re
import os
fname = "/opt/PostgreSQL/9.6/data/postgresql.conf"
outfname = fname + '.new'
with open(fname, 'r') as infile, open(outfname, 'w') as outfile:
for line in infile:
line = re.sub(r"(log_min_messages = ).*", r"1notice", line)
outfile.write(line)
os.rename(outfname, fname)
但是,您不需要正式表达式。因此,您可以省略import re
并用以下方式替换line = re.sub(....)
行
if 'log_min_messages = ' in line:
line = line.split('=')[0] + ' noticen'
in
操作员测试子字符串的存在,您可以使用line.startswith()
,但我不确定您的文件格式。请注意,我们必须在此处添加n
Newline,默认情况下re
方法(和sed
)与Newline不匹配.*
。
通常,如果您可以使用字符串方法而不是正则表达式获得作业,那么代码更简单,更有效(尽管在这种情况下您是否会看到差异)。