Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python(或Python+;Perl):在配置文件中设置值_Python_Regex_String_Bash_Sed - Fatal编程技术网

Python(或Python+;Perl):在配置文件中设置值

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

我找不到一个答案符合我要求的问题

我过去常常用bash编写脚本,但我注意到bash在处理大型操作时效率太低,所以我正在用python重写代码

但我是python的noob!所以我谷歌了很多,但这里我有一个问题。。。 在我的bash脚本中有很多sed操作,我想知道用python重新创建它的方法(这将是重写所有sed操作的起点):

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