【问题标题】:Python: Keep the existing line if not add a new line in a file?Python:如果不在文件中添加新行,则保留现有行?
【发布时间】:2016-06-30 18:15:47
【问题描述】:

如果存在现有值,我想保留现有行,否则将该行添加到文件中。我正在为 nagios 主机文件编写脚本。

主机文件:

define host{
          use             hoststatus
          host_name       linuxhost1
          alias           linuxhost1
          hostgroups      linuxgroup
          Sev             1
}
define host{
          use             hoststatus
          host_name       linuxhost2
          alias           linuxhost2
          hostgroups      linuxgroup
          Sev             2
}
define host{
          use             hoststatus
          host_name       linuxhost3
          alias           linuxhost3
          hostgroups      linuxgroup
}

define host{
          use             hoststatus
          host_name       linuxhost4
          alias           linuxhost4
          hostgroups      linuxgroup
}

我编写了这个脚本,如果该行不存在则添加该行(即 Sev 行在最后两个主机中不存在,所以如果 Sev is 存在则跳过它)对于前两个我不想添加任何东西。

代码:

import re,sys

with open(sys.argv[1],'r') as f1:
    data = f1.readlines()

txt=''

with open(sys.argv[1],'r') as f3:
    severity=True
    default=4
    vmowner=True
    default_VM = "XXXXXXXXXXXXXX"

    for line in f3:
        if line.strip().startswith('Sev'):
            severity=False

        if line.strip().startswith('Vmowner'):
            vmowner=False

    if severity:
        txt = txt + "\tSev\t\t" + str(default) + "\n"

    if vmowner:
        txt = txt + "\tVmowner\t\t" + str(default_VM) + "\n"
    txt = txt + "\tSevOwner\tYYYYYYYYYYYY\n"
    txt = txt + "}\n"

with open(sys.argv[1],'r+') as f2:
    for line in data:
        if line.strip().startswith('}'):
            line = line.replace('}',txt)
#        f2.write(line)
        print line,

但问题是我没有得到确切的输出。

生成的输出:

define host{
          use             hoststatus
          host_name       linuxhost1
          alias           linuxhost1
          hostgroups      linuxgroup
          Sev             1
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}

define host{
          use             hoststatus
          host_name       linuxhost2
          alias           linuxhost2
          hostgroups      linuxgroup
          Sev             2
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}

define host{
          use             hoststatus
          host_name       linuxhost3
          alias           linuxhost3
          hostgroups      linuxgroup
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}


define host{
          use             hoststatus
          host_name       linuxhost4
          alias           linuxhost4
          hostgroups      linuxgroup
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}

预期输出:

define host{
          use             hoststatus
          host_name       linuxhost1
          alias           linuxhost1
          hostgroups      linuxgroup
          Sev             1
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}

define host{
          use             hoststatus
          host_name       linuxhost2
          alias           linuxhost2
          hostgroups      linuxgroup
          Sev             2
        Vmowner         XXXXXXXXXXXXXX
        SevOwner        YYYYYYYYYYYY
}

define host{
          use             hoststatus
          host_name       linuxhost3
          alias           linuxhost3
          hostgroups      linuxgroup
          Sev             4
          Vmowner         XXXXXXXXXXXXXX
          SevOwner        YYYYYYYYYYYY
}


define host{
          use             hoststatus
          host_name       linuxhost4
          alias           linuxhost4
          hostgroups      linuxgroup
          Sev             4
          Vmowner         XXXXXXXXXXXXXX
          SevOwner        YYYYYYYYYYYY
}

提前致谢。

【问题讨论】:

    标签: python nagios


    【解决方案1】:

    我会这样做:

    • 读取整个文件
    • 将其拆分为块
    • 将每个块分成几行
    • 添加任何需要的数据
    • 重新制作整个区块
    • 重新制作整个文件

    from collections import OrderedDict
    
    default_sev = 4
    default_VM = "XXXXXXXXXXXXXX"
    default_sevowner = "YYYYYYYYYYYY"
    
    def add_missing(data_block):
        data_block = data_block.strip("}\n")
        lines = OrderedDict([line.split() for line in data_block.splitlines()])
        if "Sev" not in lines:
            lines["Sev"] = default_sev
        if "Vmowner" not in lines:
            lines["Vmowner"] = default_VM
        if "SevOwner" not in lines:
            lines["SevOwner"] = default_sevowner
        data = ""
        for key, value in lines.items():
            data += "          {: <16}{}\n".format(key, value)
        return "define host{{\n{}\n}}".format(data)
    
    with open(sys.argv[1]) as f1:
        data = f1.read()
    
    blocks = data.split('define host{') #split into blocks
    blocks = filter(None, blocks) #remove empty blocks
    
    with open(sys.argv[1], 'w') as f1:
        for block in blocks:
            f1.write(add_missing(block))
    

    【讨论】:

    • 当我运行你的代码时,我得到了这个错误 print add_missing(block) File "file.py", line 19, in add_missing data += " {:
    • 您使用的一定是非常旧的 python 版本。将其更改为data += " {0: &lt;16}{1}\n".format(key, value)
    【解决方案2】:

    您不会在每个主机之后将严重性标志重置为 true。这意味着第一个主机将标志设置为 false,然后永远无法输入后面的 if 语句检查标志。您需要添加逻辑来检查新主机文件的开头以重置逻辑,例如您的严重性标志。

    【讨论】:

    • 我已经找到了。知道如何以不同的方式做吗?
    • 根据您进行多少解析,您可能需要更健壮的方法。但一个简单的答案是在你的 for 循环中添加另一行检查: if line.strip().startswith('define host'): severity = True
    • 我添加了一些逻辑,但 Sev 的 for 循环对该主机重复了多次。
    • 在您发布的代码中,我看不到您如何检查主机定义的结尾。您需要添加逻辑来检查主机定义的结尾(我想在这种情况下只检查'}'),然后如果设置了标志,则添加 Sev 之类的内容,然后重置所有标志。
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多