Python(或Python+;Perl):在配置文件中设置值
我找不到一个答案符合我要求的问题 我过去常常用bash编写脚本,但我注意到bash在处理大型操作时效率太低,所以我正在用python重写代码 但我是python的noob!所以我谷歌了很多,但这里我有一个问题。。。 在我的bash脚本中有很多sed操作,我想知道用python重新创建它的方法(这将是重写所有sed操作的起点):Python(或Python+;Perl):在配置文件中设置值,python,regex,string,bash,sed,Python,Regex,String,Bash,Sed,我找不到一个答案符合我要求的问题 我过去常常用bash编写脚本,但我注意到bash在处理大型操作时效率太低,所以我正在用python重写代码 但我是python的noob!所以我谷歌了很多,但这里我有一个问题。。。 在我的bash脚本中有很多sed操作,我想知道用python重新创建它的方法(这将是重写所有sed操作的起点): sed -i -e "s/\(log_min_messages = \).*/\1notice/" "/opt/PostgreSQL/9.6/data/postgresq
sed -i -e "s/\(log_min_messages = \).*/\1notice/" "/opt/PostgreSQL/9.6/data/postgresql.conf"
将该文件中“log_min_messages”之后的所有内容替换为“notice”
基本上,打开postgresql.conf文件,搜索匹配模式“log_min_messages=*”(其中*表示在“=”后面的内容无关紧要),并用字符串“notice”替换“*”
例如:
以前
log_min_messages = something
在该命令之后:
log_min_messages = notice
我想知道我是否必须使用“re”
编辑:一个想法是在python脚本中实现Perl命令,因此,如果有人知道如何在Perl中实现这一点,这将是一个很好的答案。ConfigParser可以读取/写入ini配置文件 我不确定它是否能满足你的要求 参考: 第一步是从文件中读取配置,然后更改配置值中的值,最后将配置写回文件 嗯。。。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 = %s\n" % (key, str(value).replace('\n', '\n\t')))
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')
希望它能帮助您。ConfigParser可以读取/写入ini配置文件 我不确定它是否能满足你的要求 参考: 第一步是从文件中读取配置,然后更改配置值中的值,最后将配置写回文件 嗯。。。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 = %s\n" % (key, str(value).replace('\n', '\n\t')))
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
转换非常简单,我们必须创建一个临时文件(outname
)来写入新文本,然后重命名它。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] + ' notice\n'
在操作符中的测试子字符串的存在,您可以使用line.startswith()
来代替,但我不确定您的文件格式。请注意,我们必须在此处添加\n
换行符,默认情况下re
方法(和sed
)与*
不匹配
一般来说,如果您可以使用字符串方法而不是正则表达式来获得作业,那么代码将更简单、更高效(尽管在本例中,如果您看到差异,这一点值得怀疑)。从sed
转换非常简单,我们必须创建一个临时文件(outname
)将新文本写入,然后重命名。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] + ' notice\n'
在操作符中的测试子字符串的存在,您可以使用line.startswith()
来代替,但我不确定您的文件格式。请注意,我们必须在此处添加\n
换行符,默认情况下re
方法(和sed
)与*
不匹配
一般来说,如果您可以使用字符串方法而不是正则表达式来完成任务,那么代码会更简单、更高效(尽管在本例中,如果您看到差异,这一点值得怀疑)。也许Perl更适合?尽管如此,不幸的是,此脚本还有很多事情要做……不仅仅是“sedding”顺便问一下,我可以通过shell从python调用一些perl命令……在这种情况下,它会是什么?(编辑问题)也许一些pythoner
不熟悉bash
,所以你应该简单地解释一下,并给出一些例子。编辑问题,现在应该更清楚:)也许Perl更合适?考虑到它,不幸的是这个脚本有很多事情要做…不仅仅是“sedding”顺便问一下,我可以通过shell从python调用一些perl命令……在这种情况下,它会是什么?(也编辑问题)可能一些pythonners
不熟悉bash
,因此您应该简单地解释一下,并给出一些例子。编辑问题后,现在应该更清楚:)如果postgresql.conf有以下部分,那就太好了:(事实上,没有…一个人可以在开始时添加一个节,然后通过一些简单的命令将其删除…我会尝试一下,但我认为它实际上只适用于“标准”conf files…@WyattGillette先生,这没有问题,请参考此链接。我使用相同的方法读取此类文件。我认为不使用节来读/写配置文件是很容易的。如果只有postgresql.conf有节,那就太好了:(事实上,没有…一个人可以在开始时添加一个节,然后通过一些简单的命令将其删除…我会尝试一下,但我认为它实际上只适用于“标准”conf文件…@WyattGillette先生,这没有问题,请参考这个链接,我用同样的方法来读取这些文件。我认为这很容易改进为读/写con