使python configobj在'='前后不放空格



简单的问题。有可能使configobj不在配置项中的'='之前和之后放置空格?

我使用configobj读取和写入一个文件,该文件稍后由bash脚本处理,因此输入像

这样的字符:

VARIABLE = "value"

会破坏bash脚本,它需要始终是:

变量= "价值"

或者如果有人有其他关于如何读写具有此类条目(和限制)的文件的建议,也可以。

谢谢

我正在查看相同的和修改的configobj.py通过更改第1980行:

def _write_line(self, indent_string, entry, this_entry, comment)
来自:

self._a_to_u(' = ')

:

self._a_to_u('=')

修改后,输出等于号前后没有空格

Configobj用于读写ini样式的配置文件。显然,您试图使用它来编写bash脚本。这是行不通的。

只要按照你想要的方式编写bash脚本,也许可以使用模板或其他东西。

要使ConfigParses不写=周围的空格可能需要子类化它。我猜您必须修改write方法,但只有阅读代码才能有所帮助。: -)

那么,正如建议的那样,我最终为这个编写了自己的解析器,可以完全以与ConfigObj相同的方式使用:

config = MyConfigParser("configuration_file")
print config["CONFIG_OPTION_1"]  
config["CONFIG_OPTION_1"]= "Value 1"
print config["CONFIG_OPTION_1
config.write()

这是代码,如果有人感兴趣或想要给出建议(我开始在python编码不是这么久以前,所以可能有很多改进的空间)。它尊重文件中注释和选项的顺序,并在需要的地方正确地转义和添加双引号:

import os
import sys
class MyConfigParser:
  name = 'MyConfigParser'
  debug = False
  fileName = None
  fileContents = None
  configOptions = dict()  
  def __init__(self, fileName, debug=False):
    self.fileName = fileName
    self.debug = debug    
    self._open()
  def _open(self):       
    try:
        with open(self.fileName, 'r') as file:
    for line in file:
      #If it isn't a comment get the variable and value and put it on a dict
      if not line.startswith("#") and len(line) > 1:
    (key, val) = line.rstrip('n').split('=')
    val = val.strip()
    val = val.strip('"')
    val = val.strip(''')
    self.configOptions[key.strip()] = val
except:
  print "ERROR: File "  + self.fileName + " Not Foundn"
  def write(self):
try:
  #Write the file contents
  with open(self.fileName, 'r+') as file:
    lines = file.readlines()
    #Truncate file so we don't need to close it and open it again 
    #for writing
    file.seek(0)
    file.truncate()      
    i = 0
    #Loop through the file to change with new values in dict      
    for line in lines:    
      if not line.startswith("#") and len(line) > 1:
    (key, val) = line.rstrip('n').split('=')
    try:
      if key in line:
        newVal = self.configOptions[key]
        #Only update if the variable value has changed
        if val != newVal:
          newLine = key + "="" + newVal + ""n"
          line = newLine
    except:
      continue
      i +=1
      file.write(line)
except IOError as e:
  print "ERROR opening file " + self.fileName + ": " + e.strerror + "n"

  #Redefinition of __getitem__ and __setitem__
  def __getitem__(self, key):  
try:
  return self.configOptions.__getitem__(key)
except KeyError as e:
  if isinstance(key,int):
    keys = self.configOptions.keys()
    return self.configOptions[keys[key]]
  else:
    raise KeyError("Key " +key+ " doesn't exist")
  def __setitem__(self,key,value):
self.configOptions[key] = value

如上所述,可以通过对_write_line方法做一个小更改来删除等号两侧的空格。这可以通过子类化ConfigObj并覆盖_write_line来方便地完成,如下所示-

from configobj import ConfigObj
class MyConfigObj(ConfigObj):
    def __init__(self, *args, **kwargs):
        ConfigObj.__init__(self, *args, **kwargs)
    def _write_line(self, indent_string, entry, this_entry, comment):
        """Write an individual line, for the write method"""
            # NOTE: the calls to self._quote here handles non-StringType values.
        if not self.unrepr:
            val = self._decode_element(self._quote(this_entry))
        else:
            val = repr(this_entry)
        return '%s%s%s%s%s' % (indent_string,
                           self._decode_element(self._quote(entry, multiline=False)),
                           self._a_to_u('='),
                           val,
                           self._decode_element(comment))

然后使用MyConfigObj来代替ConfigObj, ConfigObj的所有功能都被保留

正如Lennart所建议的,configobj可能不是适合这项工作的工具:

>>> import pipes
>>> def dict2bash(d):
...     for k, v in d.iteritems():
...         print "%s=%s" % (k, pipes.quote(v))
...         
>>> dict2bash({'foo': "bar baz quux"})
foo='bar baz quux'

由于configobj返回的东西看起来很像字典,您可能仍然可以使用它读取您试图处理的数据。

首先,感谢Juancho。这就是我要找的。但我编辑了ConfigParser一点点。现在它可以处理以下形式的bash脚本数组:

# Network interfaces to be configured
ifaces=( "eth0" "eth1" "eth2" "eth3" )

如果你设置了一个值,它只是证明这个值是否是一个列表,如果,它正确地设置了引号。所以你仍然可以用同样的方式设置值,即使它是一个列表:

ifaces = ['eth0', 'eth1', 'eth2', 'eth3']
conf['ifaces'] = ifaces

代码如下:

import os
import sys
class MyConfigParser:
    name = 'MyConfigParser'
    debug = False
    fileName = None
    fileContents = None
    configOptions = dict()  
    qouteOptions = dict()
    def __init__(self, fileName, debug=False):
        self.fileName = fileName
        self.debug = debug    
        self._open()
    def _open(self):       
        try:
            with open(self.fileName, 'r') as file:
                for line in file:
                    #If it isn't a comment get the variable and value and put it on a dict
                    if not line.startswith("#") and len(line) > 1:
                        (key, val) = line.rstrip('n').split('=')
                        val = val.strip()
                        val = val.strip('"')
                        val = val.strip(''')
                        self.configOptions[key.strip()] = val
                        if val.startswith("("):
                            self.qouteOptions[key.strip()] = ''
                        else:
                            self.qouteOptions[key.strip()] = '"'
        except:
            print "ERROR: File "  + self.fileName + " Not Foundn"
    def write(self):
        try:
            #Write the file contents
            with open(self.fileName, 'r+') as file:
                lines = file.readlines()
                #Truncate file so we don't need to close it and open it again 
                #for writing
                file.seek(0)
                file.truncate()      
                #Loop through the file to change with new values in dict      
                for line in lines:
                    if not line.startswith("#") and len(line) > 1:
                        (key, val) = line.rstrip('n').split('=')
                        try:
                            if key in line:
                                quotes = self.qouteOptions[key]
                                newVal = quotes +  self.configOptions[key] + quotes
                                #Only update if the variable value has changed
                                if val != newVal:
                                    newLine = key + "=" + newVal + "n"
                                    line = newLine
                        except:
                            continue
                    file.write(line)
        except IOError as e:
                print "ERROR opening file " + self.fileName + ": " + e.strerror + "n"

    #Redefinition of __getitem__ and __setitem__
    def __getitem__(self, key):  
        try:
            return self.configOptions.__getitem__(key)
        except KeyError as e:
            if isinstance(key,int):
                keys = self.configOptions.keys()
                return self.configOptions[keys[key]]
            else:
                raise KeyError("Key " + key + " doesn't exist")
    def __setitem__(self, key, value):
        if isinstance(value, list):
            self.qouteOptions[key] = ''
            value_list = '('
            for item in value:
                value_list += ' "' + item + '"'
            value_list += ' )'
            self.configOptions[key] = value_list
        else:
            self.qouteOptions[key] = '"'
            self.configOptions[key] = value

最新更新