python初级之路-文件增删查
前言:
老板现在给你任务,公司有haproxy配置文件,希望通过python程序可以对ha配置文件进行增删改。
思路:
1、要求用户输入相应的数字,判断用户需要进行的操作,然后再让用户输入需要操作的backend数据。
2、当用户输入数字“1”时,提示用户输入需要查询的数据,并将查询的数据信息打印到屏幕。
3、当用户输入数字“2”时,提示用户输入需要新增的数据,并将用户输入的字符串转换成字典类型,然后调用add_data()方法执行新增操作。add_data()方法会先去调用fetch()方法,将原文件中匹配到的数据保存到fetch_list列表中,如果fetch_list列表有数据,则通过for循环将原文件haproxy.txt的内容一行一行读取出来,同时将读取到的内容一行一行的写入到新文件haproxy.new中,当匹配到需要新增的backend行时,先将原有的数据写入到新文件,再将用户输入新增的数据插入对应的位置;如果fetch_list列表没有数据,则一边读取原文件haproxy.txt的内容,一边将内容写入到新文件haproxy.new中,原文件内容循环完毕后再将用户输入的新增backend数据写入到新文件haproxy.new中,最后通过os.rename()修改两个文件的名称。
4、当用户输入数字“3”时,提示用户输入需要删除的数据,并将用户输入的字符串转换成字典类型,然后调用delete_data()方法执行删除操作。delete_data()方法会先去调用fetch()方法,将原文件中匹配到的数据保存到fetch_list列表中,如果fetch_list列表没有数据,则提示用户“没有找到需要删除的数据”,如果fetch_list列表仅有一条数据且与用户输入需要删除的数据匹配时,需要将匹配到的backend和backend数据行一并删除,否则只删除backend数据行,最后通过os.rename()修改两个文件的名称。
代码实现:

1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 4 import json, os 5 6 # 定义fetch()方法,逐行匹配用户输入的backend 7 def fetch(backend): 8 flag = False # 定义flag,用于判断后面是否有可取的backend 9 fetch_list = [] # 用于存放匹配到的backend的值 10 with open('haproxy.txt', 'r') as f: # 以读取的方式打开haproxy.txt文件 11 for line in f: # 逐行循环文件内容 12 if line.strip() == "backend %s" % backend: # 判断用户输入的backend是否与haproxy.txt文件中backend匹配 13 flag = True # 将flag设置为True,为获取backend后面的值 14 continue # 退出本次循环 15 if not line.strip().startswith("server"): # 当flag=True时,判断每行如果不以“server”开头,则重新将flag改为False 16 flag = False 17 if flag and line.strip(): 18 fetch_list.append(line.strip()) # 将匹配到的backend值添加到fetch_list列表 19 return fetch_list # 返回fetch_list 20 21 # 定义add_data()方法,将用户输入的数据添加至haproxy.txt文件 22 def add_data(data_dict): 23 backend_title = data_dict["backend"] # 获取要添加的backend的值 24 backend_context = "backend %s" % backend_title # 需要添加的backend整个字段 25 record_title = data_dict["record"] # 获取record的值 26 # 获取需要添加的信息 27 record_context = "server %s %s weight %s maxconn %s" % (record_title["server"], record_title["server"], record_title["weight"], record_title["maxconn"]) 28 # 调用fetch()方法,将haproxy.txt文件中匹配到的backend值保存到fetch_list列表中 29 fetch_list = fetch(backend_title) 30 31 if fetch_list: # 如果用户输入的backend存在haproxy.txt文件中 32 flag = False # 定义一个flag,用于找到需要添加的backend内容 33 with open('haproxy.txt', 'r') as read_file, open('haproxy.new', 'w') as write_file: # 定义一个只读和一个只写的文件对象 34 for line in read_file: # 循环原文件对象的每一行 35 if line.strip() == backend_context: # 判断用户输入的backend是否与原文件中的backend匹配 36 write_file.write(line) # 将匹配的backend写入到新文件中 37 flag = True # 修改flag值 38 continue # 退出此次循环 39 if not line.strip().startswith("server"): 40 flag = False 41 if flag and line.strip(): # 当flag标签为True时执行 42 if line.strip() == record_context: # 如果用户输入的bakend的值存在原文件中,就只讲原文件的数据到新文件中 43 print("您输入的backend值%s已经存在。" % record_context) 44 write_file.write(line) 45 else: 46 write_file.write(line) # 将匹配的backend原有的数据写入到新文件中 47 fetch_list.remove(line.strip()) # 在fetch_list列表中移除已写入新文件中的数据 48 if len(fetch_list) == 0: # 当fetch_list列表等长度为0时候,插入用户新增的数据 49 new_line = "%s%s" % (" "*8, record_context) 50 write_file.write(new_line + "\n") # 将用户新增的数据插入到新文件中 51 else: 52 write_file.write(line) # 当上述的条件都不满足的情况下,将原文件的数据写入到新文件中 53 else: # 如果用户输入的backend不存在haproxy.txt文件中 54 with open('haproxy.txt', 'r') as read_file, open('haproxy.new', 'w') as write_file: # 定义一个只读和一个只写的文件对象 55 for line in read_file: # 循环原文件对象的每一行 56 write_file.write(line) # 将原文件的每一行数据写入到新文件中 57 write_file.write("\n\n" + backend_context + "\n") # 在新文件的末尾追加用户输入的backend 58 new_line = "%s%s" % (" "*8, record_context) 59 write_file.write(new_line + "\n") # 在新文件的末尾追加用户输入的backend值 60 61 os.rename("haproxy.txt", "haproxy.bak") # 备份原文件 62 os.rename("haproxy.new", "haproxy.txt") # 将新文件重命名成haproxy.txt 63 64 # 定义delete_data()方法,删除haproxy.txt文件中匹配的数据 65 def delete_data(data_dict): 66 backend_title = data_dict["backend"] # 获取要删除的backend的值 67 backend_context = "backend %s" % backend_title # 需要删除的backend整个字段 68 record_title = data_dict["record"] # 获取需要删除的record值 69 # 获取需要删除的信息 70 record_context = "server %s %s weight %s maxconn %s" % (record_title["server"], record_title["server"], record_title["weight"], record_title["maxconn"]) 71 # 调用fetch()方法,将haproxy.txt文件中匹配到的backend值保存到fetch_list列表中 72 fetch_list = fetch(backend_title) 73 if not fetch_list or record_context not in fetch_list: # 如果在文件中没有找到需要删除的数据,则提示用户没有可以删除的数据 74 print("Sorry, 没有找到需要删除的数据。") 75 return 76 else: 77 with open('haproxy.txt', 'r') as read_file, open('haproxy.new', 'w') as write_file: 78 flag = False # 定义一个flag,用于找到需要删除的backend行 79 if len(fetch_list) == 1 and record_context in fetch_list: # 如果原文件backend只有一行数据,且需要删除,则连带backend一起删除 80 for line in read_file: 81 if line.strip() == backend_context: # 找到需要删除的backend行 82 flag = True 83 continue 84 if not line.strip().startswith("server"): 85 flag = False 86 if flag and line.strip(): # 匹配到backend的数据时,只打印输出信息,不做写入动作 87 print('%s数据已被删除。' % (data_dict)) 88 else: 89 write_file.write(line) 90 else: # 如果原文件backend数据有多条时,将需要删除的数据删除,其他输入正常写入新文件中 91 for line in read_file: 92 if line.strip() == backend_context: # 找到需要删除的backend行 93 write_file.write(line) # 将backend信息写入到新文件 94 flag = True 95 continue 96 if not line.strip().startswith("server"): 97 flag = False 98 if flag and line.strip(): 99 if line.strip() == record_context: # 当匹配到需要删除的数据时,打印删除信息,不做写入动作 100 print('[%s]数据已被删除。' % record_context) 101 else: 102 write_file.write(line) # 其他backend数据则继续写入新文件中 103 else: 104 write_file.write(line) 105 106 os.rename("haproxy.txt", "haproxy.bak") # 备份原文件 107 os.rename("haproxy.new", "haproxy.txt") # 将新文件重命名成haproxy.txt 108 109 # 主函数 110 def main(): 111 print("1、查询\n2、添加\n3、删除\n") 112 # 根据用户输入的数字进行选择对文件进行相关的操作 113 select_num = input("请输入上面对应的数字: ") 114 if select_num == "1": 115 print() 116 backend = input("请输入需要查询的backend: ") 117 fetch_list = fetch(backend) 118 for i in fetch_list: 119 print(i) 120 else: 121 print() 122 print("输入参考样例:", '{"backend":"ttt.oldboy.org","record":{"server":"100.1.7.9","weight":"20","maxconn":"3000"}}') 123 data_str = input("请按样例输入: ") 124 data_dict = json.loads(data_str) # 因为input()方法接收用户输入的类型为字符串,所以需要通过json函数将类似字典的字符串转换成字典类型 125 if select_num == "2": 126 add_data(data_dict) 127 elif select_num == "3": 128 delete_data(data_dict) 129 else: 130 print("输入错误") 131 132 if __name__ == "__main__": 133 main()

1 global 2 log 127.0.0.1 local2 3 daemon 4 maxconn 256 5 log 127.0.0.1 local2 info 6 defaults 7 log global 8 mode http 9 timeout connect 5000ms 10 timeout client 50000ms 11 timeout server 50000ms 12 option dontlognull 13 14 listen stats :8888 15 stats enable 16 stats uri /admin 17 stats auth admin:1234 18 19 frontend oldboy.org 20 bind 0.0.0.0:80 21 option httplog 22 option httpclose 23 option forwardfor 24 log global 25 acl www hdr_reg(host) -i www.oldboy.org 26 use_backend www.oldboy.org if www 27 28 backend www.oldboy.org 29 server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000 30 server 100.1.7.19 100.1.7.19 weight 20 maxconn 3000 31 32 listen stats :9999 33 stats enable 34 stats uri /admin 35 stats auth admin:1234 36 37 backend buy.oldboy.org 38 server 100.1.7.90 100.1.7.90 weight 20 maxconn 3000
实现效果: