Python 读写一个配置文件的实例分解 (二)

上次已经进行了图解。本次将展示一些主要的函数:

##################################### 1 服务器组展示函数:sys_show() ####################

def sys_show(file):
    sys_zone_name = ‘backend‘  ### 搜索关键字, 系统组名称 ###
    srv_zone_name = ‘‘  ### 搜索关键字,服务器组的名称 ,例如:Oracle ###
    svr_name = ‘server‘  ###搜索关键字,服务器关键字###

    srv_zone_names_list = []  ### 服务器组名称sys_zone_name组成的列表 ###
    srv_zone_names_dict = {}  ### 服务器组名称sys_zone_name组成的字典,返回该值 ###
    svr_zones_dict = defaultdict(list)  ### 各服务器组名称(srv_zone_name)和对应服务器详细参数(svr_record_dict{})组成的字典 ,返回该值###

    svr_record_dict = OrderedDict()  ### 包含服务器详细参数有序字典 ###
    svr_record_list = []  ### svr_record_dict{} 的列表形式###

    svr_name_flag = False  ### 标记是否找到该服务组(srv_zone_name)的标志###

    with open(file, mode=‘r‘, encoding=‘UTF-8‘) as cfg_file:
        for line in cfg_file.readlines():
            line = line.strip(‘\n‘)
            if re.match(sys_zone_name, line):  ###  系统组名称 sys_zone_name 如果在line中 ###
                srv_zone_name = re.split(‘\s+‘, line)[1]  ###  取得 srv_zone_name值 ###
                srv_zone_names_list.append(srv_zone_name)  ###  将srv_zone_name值存入列表 srv_zone_names_list中 ###
                svr_name_flag = True  ### 找到 对应的系统 sys_zone_name ###
            elif svr_name_flag and re.match(‘\s+server‘, line):  ### 在该系统 sys_zone_name下,如果存在svr_name关键字 ###
                svr_record_list = re.split(‘\s+‘, line)  ### 该行以 空格 为分隔符 将具体信息 存入 svr_record_list[]中 ###

                svr_record_dict = OrderedDict()
                ### 在定义新参数前,归位svr_record_dict,,否则会使用下面的新参数覆盖所有原先的赋值###

                svr_record_dict[‘server_name‘] = svr_record_list[2]
                svr_record_dict[‘IP_address‘] = svr_record_list[4]
                svr_record_dict[‘weight‘] = svr_record_list[6]
                svr_record_dict[‘maxconn‘] = svr_record_list[8]
                ###取出列表svr_record_list 的信息,存入svr_record_dict{}字典中###

                svr_zones_dict[srv_zone_name].append(svr_record_dict)  ### 将srv_zone_name 与 svr_record_dict关联 ###
            else:
                svr_name_flag = False

    for k, v in enumerate(srv_zone_names_list, 1):
        srv_zone_names_dict[k] = v  ###对srv_zone_names_list进行新字典赋值###
        print(‘              \033[34m %d . %-6s 服务器组 \033[0m‘ % (k, v))  ###输出 带编号的 服务器组 名称###

    return srv_zone_names_dict, svr_zones_dict  ###返回srv_zone_names_dict字典 和svr_zones_dict 字典###
#########################################################################################

效果图:

下面是服务器展示函数:

#################################### 4 服务器展示函数 srv_record_show () ################
def srv_record_show(srv_zone_name, svr_zones_dict):
    ############对sys名称进行遍历并加上数字编号###########################
    print(‘\n================================================================================‘)
    print(‘(%s)服务器信息如下 : ‘ % srv_zone_name)
    print(‘%-5s %-18s %-18s %-18s %-18s‘ % (‘id‘, ‘name‘, ‘address‘, ‘weight‘, ‘maxconn‘))

    svr_detail = svr_zones_dict[srv_zone_name]
    for k, v in enumerate(svr_detail, 1):  ###用enumerate进行unit_record展示###
        print(‘%-5s ‘ % k, end=‘‘)
        for kk, vv in v.items():
            print(‘%-18s‘ % vv, end=‘|‘)
        print()
    print(‘\n=========================================================================‘)
#########################################################################################

效果图如下:

#################################### 8 配置文件回写函数 wrt2cfg() #######################
def wrt2cfg(file, svr_zones_all_dict):
    newfile = ‘%s.new‘ % file  ###定义回写的新文件###
    svr_name_flag = False

    ###同时开启2个文件,分别进行读写###
    with open(file, ‘r‘, encoding=‘UTF-8‘) as read_file, open(newfile, ‘w‘, encoding=‘UTF-8‘) as write_file:

        for line in read_file:
            if re.match(‘backend‘, line):  ###读取read_file,匹配至backend行时###
                write_file.write(line)  ###将本行插入到write_file中。###

                srv_zone_name = re.split(‘\s+‘, line)[1]
                for srv_dict in svr_zones_all_dict[srv_zone_name]:  ###对svr_zones_all_dict字典进行遍历###
                    server_line = ‘\t server {server_name} IP {IP_address} weight {weight} maxconn {maxconn}\n‘
                    write_file.write(server_line.format(**srv_dict))  ###将srv_zone_name下的server行插入到write_file###

                    svr_name_flag = True  ###读取到read_file中以server开头的行,将该行svr_name_flag标记为真###
            elif svr_name_flag and re.match(‘\s+server‘, line):
                ###读取read_file,匹配至server开头的行时跳过,对write_file不做任何操作###
                pass
            else:
                write_file.write(line)  ###将read_file其他的行直接插入到write_file中###
                svr_name_flag = False  ###读取read_file,未发现以server开头的行时,将该行server_flag标记为FALSE###
    print(‘\033[39m 配置文件 更新成功\033[0m‘)
    os.system(‘move %s %s.bak ‘ % (file, file))  ###对源文件read_file进行备份###
    os.system(‘move %s %s‘ % (newfile, file))  ##对新生成的write_file进行改名###
#########################################################################################
#################################### 9 更新服务器数据函数 update_svr_dict()#############
def update_svr_dict (new_svr_dict,update_select_num) :
    old_select_num = update_select_num
    (new_svr_dict[‘server_name‘], update_select_num) = name_filter(update_select_num)  ###对name检查###
    if old_select_num == update_select_num :
        (new_svr_dict[‘IP_address‘], update_select_num) = ipaddress_filter(update_select_num)  ###对IP检查###
    if old_select_num == update_select_num :
        (new_svr_dict[‘weight‘], update_select_num) = number_filter(‘权重值‘,update_select_num)  ###对权重检查###
    if old_select_num == update_select_num :
        (new_svr_dict[‘maxconn‘], update_select_num) = number_filter(‘最大连接数‘,update_select_num)  ###对最大连接数检查###
    if old_select_num == update_select_num :
        print (new_svr_dict[‘server_name‘], new_svr_dict[‘IP_address‘], new_svr_dict[‘weight‘], new_svr_dict[‘maxconn‘])
    return (new_svr_dict,update_select_num)
#########################################################################################

主程序如下:

##################################主程序开始#############################################
if __name__ == ‘__main__‘:
    flag = True  ### 脚本运行的标志 ###
    sys_zone_name_ky = ‘backend‘  ### 系统的 名称 ###
    srv_zone_name_vl = ‘‘  ### 服务器组的名称 例如:Oracle
    sys_cfg_file = ‘configuretion.cfg‘  ###指定sys的配置文件###
    svr_zones_all_dict = {}  ### svr_zones_all_dict字典 记录各服务器的详细信息 ###
    srv_zone_all_names_dict = {}  ### svr_name_ky 字典(由svr_name_ky列表和 数字编号 组成的字典)###
    global_opt2 = ‘‘
    srv_zone_name_vl_num = ‘‘

    while flag:    ### 循环M ###
        os.system(‘cls‘)  ###清屏###
        print(‘\n \033[38m ================================================================‘)
        print(‘            \033[36m 欢迎使用 数据库服务器 配置文件管理平台:\033[0m‘)

        print(‘\033[32m ================================================================‘)
        print(‘‘‘        \033[39m 1. 查询具体服务器\033[0m
        \033[34m 2. 添加具体服务器\033[0m
        \033[39m 3. 修改服务器列表\033[0m
        \033[34m 4. 删除服务器列表\033[0m
        \033[31m 0. 退出\033[0m ‘‘‘)
        print(‘================================================================‘)

        select_num = input(‘\033[30m 请按 数字键(0~4) 选择:\033[0m‘)

        ##################################### 0 退出 exit ###############################
        if select_num == ‘0‘:
            flag = False
            continue
        while select_num in [‘1‘,‘2‘,‘3‘,‘4‘] :    ### 循环 0 ###
            if select_num == ‘1‘:temp_vl = ‘查看‘  #temp_vl 为下一步显示对应选定的操作而设置的临时参数
            if select_num == ‘2‘:temp_vl = ‘添加‘
            if select_num == ‘3‘:temp_vl = ‘修改‘
            if select_num == ‘4‘:temp_vl = ‘删除‘
            old_select_num = select_num

            print(‘\n              %-8s ZONE 服务器组信息如下 : ‘ % sys_zone_name_ky)
            (srv_zone_all_names_dict, svr_zones_all_dict) = sys_show(sys_cfg_file)
            print(‘\033[32m ================================================================‘)

            input_content = input(‘\033[39;1m请输入进行\033[33;1m%s\033[0m操作的服务器组的编号或名称‘                                   ‘(返回主菜单,请输入B or b):\033[0m‘ % temp_vl )
            ############################## 对输入值进行过滤 #############################
            (srv_zone_name_vl, tmp_flag) = content_filter(input_content, srv_zone_all_names_dict)
            if srv_zone_name_vl:  ###显示对应 srv_zone 下的服务器列表###
                srv_record_show(srv_zone_name_vl, svr_zones_all_dict)

            if tmp_flag == False : break
            ##################################### 1 查询服务器信息 ######################
            if select_num == ‘1‘: continue
            ##################################### 2. 更新服务器信息 #####################
            while select_num == old_select_num and srv_zone_name_vl:    ### 循环1 ###
                if select_num in [ ‘3‘, ‘4‘ ]:    ###判断修改、删除选项中输入的服务器编号准确性###
                    srv_zone_name_vl_num = input(‘\033[32;1m请输入\033[33;1m%s\033[0m的服务器的编号,((N|n)返回上级菜单):\033[0m‘% temp_vl)
                    if srv_zone_name_vl_num in [‘N‘, ‘n‘]: break
                    if len(srv_zone_name_vl_num) != 0:
                        srv_zone_name_vl_num = input_str2int(srv_zone_name_vl_num)
                    #####################指定具体的server编号进行判断#####
                    elif srv_zone_name_vl_num not in range(1, len(svr_zones_all_dict[srv_zone_name_vl]) + 1):
                        print(‘超出范围,请重新输入!!!‘)
                        continue        ###srv_zone_name_vl_num不在在服务器组个数范围之内,提示并重新选择###
                if select_num in [ ‘2‘,‘3‘ ]:    ###添加和修改服务器时进行的操作步骤:更新服务器列表###
                    update_srv_dict = OrderedDict()
                    (update_srv_dict, select_num) = update_svr_dict(update_srv_dict,select_num)
                if select_num in [ ‘4‘ ]:
                    print(svr_zones_all_dict[srv_zone_name_vl][srv_zone_name_vl_num - 1]) #显示被选中删除的服务器列表#
                if select_num == old_select_num :   ###如果在以上操作中没有进行取消操作,则选择参数不会变化,维持原来的用户操作。###
                    update_opt = input(‘(Y|y)\033[33;1m%s\033[0m此服务器,任意键取消:‘ % temp_vl)
                    if update_opt in [‘y‘,‘Y‘]:
                        if select_num == ‘2‘:
                            svr_zones_all_dict[srv_zone_name_vl].append(update_srv_dict)
                        if select_num == ‘3‘:
                            svr_zones_all_dict[srv_zone_name_vl][srv_zone_name_vl_num - 1] =update_srv_dict
                        if select_num == ‘4‘:
                            del svr_zones_all_dict[srv_zone_name_vl][srv_zone_name_vl_num - 1]

                        wrt2cfg(sys_cfg_file, svr_zones_all_dict)
                        srv_record_show(srv_zone_name_vl, svr_zones_all_dict)
                        print(‘\033[33;1m%s\033[0m成功!‘ % temp_vl)
                else :    ###如果在添加、修改、删除过程中,选择了取消,则select_num=5 ,对应操作皆被取消###
                    print("\033[33;1m%s\033[0m被取消"  % temp_vl)
                global_opt2 = input(‘(Y|y)继续\033[33;1m%s\033[0m本组服务器,(N|n)返回重新选择服务器组,(B|b)返回主菜单:‘ % temp_vl)
                ###以上所有操作完成后,根据用户需求,修正select_num 数值,提示用户下一步操作。###
                if global_opt2 in [‘B‘, ‘b‘]:       ### 遇到select_num =  ‘5‘时,返回主菜单。###
                    select_num =  ‘5‘
                    print("返回主菜单。")
                elif global_opt2 in [‘N‘, ‘n‘]:     ###用户继续选择服务器组,继续进行对原来的操作select_num =  old_select_num,。###
                    select_num =  old_select_num
                    break
                else: select_num = old_select_num   ###在原来选择的服务器组中,继续进行操作。###
    else:
        sys.exit(‘\033[36m 程序退出,欢迎使用,谢谢! \033[0m‘)
#########################################################################################

部分截图如下:

时间: 2024-11-02 10:00:23

Python 读写一个配置文件的实例分解 (二)的相关文章

Python 读写一个配置文件的实例分解 (一)

给出的配置文件:configuration.cfg frontend testserver         servername 10.5.7.9          IP 10.5.7.9         port 8080  backend Oracle         servername 10.5.7.11 IP 10.5.7.11 weight 20 maxconn 2000         servername 10.5.7.12 IP 10.5.7.12 weight 30 maxc

python读写修改配置文件(ini)

python 有时候参数需要保存到配置文件中  接下来总结一下 配置文件的读写和修改的操作 代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- # 读取配置文件 import ConfigParser config = ConfigParser.ConfigParser() config.readfp(open('update.ini')) a = config.get("ZIP","MD5") print a #

【实例分解二】angularjs根据路由按需加载Controller

开始笔记之前,把早上检测到的angularjs中的命名问题做一下记录. 检测工具:google浏览器扩展工具angularJS,结果如下: angularjs中,module要遵守lowerCamelCase原则,例:"myApp"; controller要遵守UpperCamelCase原则并且要以Controller结尾,例:"MainController". 这一篇笔记主要对angularjs根据路由按需加载Controller的操作进行了说明,也就是上一篇中

matlab文件读写处理实例(二)——textread批量读取文件

问题:对文件夹下所有文件进行批量读取,跳过文件头部分,读取每个文件数据部分的7,8,9列,保存到变量并且输出到文件. 数据: 文件夹11m\  单个文件格式: DAV1                                                        MARKER NAME66010M001                                                   MARKER NUMBER     7    PR    TD    HR  

一个spring jdbc实例

一.使用示例 (1)springJdbcContext.xml Java代码   <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context

python常用运维脚本实例【转】

file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 . 首先open是内置函数,使用方式是open('file_name', mode, buffering),返回值也是一个file对象,同样,以写模式打开文件如果不存在也会被创建一个新的. f=open('/tmp/hello','w') #open(路径+文件名,读写模式) #读写模式:r只读,r+读写,

我的python学习--第十四天(二)

一.ansible api 在了解python的ansible api之前,先简单了解一下ansible. ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批量程序部署.批量运行命令等功能. ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.主要包括: 连接插件connection p

Python文件和目录操作实例代码

对于文件和目录的处理,虽然可以通过操作系统命令来完成,但是Python语言为了便于开发人员以编程的方式处理相关工作,提供了许多处理文件和目录的内置函数.重要的是,这些函数无论是在Unix.Windows还是Macintosh平台上,它们的使用方式是完全一致的. 本文将详细解释这些函数的使用方法.首先,介绍Python语言中类似于Windows系统的dir命令的列出文件功能,然后描述如何测试一个文件名对应的是一个标准文件.目录还是链接,以及提取文件大小和日期的方法.之后,还将介绍如何删除文件和目录

python学习笔记5:python读写文件

python学习笔记5:python读写文件 一.文件的打开模式 1.打开文件 1) f=open('D:\\a.txt','w') 第一个参数是文件的路径,如果只写文件的名字,默认是在当前执行目录下的文件:第二个参数是文件的打开模式 这种方式打开文件,在使用完了之后一定要记得,关闭文件: f.close() 2) with open('D:\\a.txt','w') as f 这种方式打开文件,文件在使用完后会自动关闭文件,不需要close  2. 文件的打开模式 总的来说,文件的打开模式有三