【问题标题】:Joining similar sections from configparser从 configparser 加入类似的部分
【发布时间】:2020-07-19 19:06:21
【问题描述】:

早上好,

我有一个包含如下数据的配置文件:

[hostset 1]
ip = 192.168.122.136
user = test
password =
pkey = ~/.ssh/id_rsa

[hostset 2]
ip = 192.168.122.138
user = test
password =
pkey = ~/.ssh/id_rsa

如果其他值相同,我希望能够在此配置文件中加入任何给定数量的主机集的 ips,因此摄取和格式化的数据将存储在 dict 中,如下所示:

{
 ip: ['192.168.122.136', '192.168.122.138'],
 user: 'test',
 password: '',
 pkey: '~/.ssh/id_rsa',
}

通过做类似的事情:

from configparser import ConfigParser


def unpack(d):
    return [value for key, value in d.items()]


def parse(configuration_file):
    parser = ConfigParser()
    parser.read(configuration_file)

    hosts = [unpack(connection) for connection in [section for section in dict(parser).values()]][1:]

    return [i for i in hosts]


if __name__ == '__main__':
    parse('config.ini')

我可以得到一个包含配置文件元素的列表列表,像这样:

[['192.168.122.136', 'test', '', '~/.ssh/id_rsa'], ['192.168.122.138', 'test', '', '~/.ssh/id_rsa']]

然后我只需要一种比较两个列表的方法,如果除了 ip 之外所有元素都相似,则将它们加入一个列表,如下所示:

[['192.168.122.136','192.168.122.138'], 'test', '', '~/.ssh/id_rsa']

所以我只需要一种聪明的方法来处理没有特定长度的列表并加入所有类似的列表。

【问题讨论】:

  • 你试过什么?你在用configparser吗?
  • 是的,我目前正在使用 configparser 读取 .ini 文件:python from configparser import ConfigParser parser = ConfigParser() parser.read('config.ini') 如果我们使用 dict() 查看它,它将返回如下内容:python {'DEFAULT': <Section: DEFAULT>, 'hostset 1': <Section: hostset 1>, 'hostset 2': <Section: hostset 2>}
  • 问题是如何巧妙地遍历所有部分以检查匹配的用户/密钥/密码,然后通过 ip 加入这些部分。

标签: python python-3.x ini


【解决方案1】:

得到朋友的帮助并解决了这个问题。关键是将我想要比较的值变成一个元组,使该元组成为字典的键和 ips 的值。由此。我可以断言,如果元组键已经存在,那么我会将 ip 附加到值中。

from configparser import ConfigParser
from ast import literal_eval as literal


def unpack(d):
    return [value for key, value in d.items()]


def parse(configuration_file):
    parser = ConfigParser()
    parser.read(configuration_file)

    hosts = [unpack(connection) for connection in [section for section in dict(parser).values()]][1:]

    d = dict()
    for item in hosts:
        try:
            d[str((item[1:]))].append(item[0])
        except KeyError:
            d[str((item[1:]))] = [item[0]]

    return d


if __name__ == '__main__':
    for k, v in parse('config.ini').items():
        print([v, *literal(k)])

【讨论】:

    【解决方案2】:

    在此解决方案中,我假设文件格式与问题中的描述完全相同: 首先我们拆分主机集: 我们假设您的数据在 rowdata 变量中

    HostSets = rowdata.split("[hostset ") # first element is empty
    Dict = {}
    
    for i in range (1,len(HostSets)):
        l = HostSets[i].split("ip = ")#two elements the first is trash
        ip = l[1].split()[0]
        conf =l[1].split("\n",1 )[1] #splits only the first element 
        try :
            Dict[conf].append(ip)
        except :
            Dict[conf] = list()
            Dict[conf].append(ip)        
    print('{')
    for element in Dict:
        print("ip: ",Dict[element],",",element)
    print('}')
    

    【讨论】:

    • 我刚刚编辑了我的问题,以便更清楚地说明我在问什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多