对于真正长期存在的问题的猜测。
我正在尝试读取配置文件并获取规则列表。 我曾尝试使用ConfigParser来执行此操作,但它不是标准配置文件。 该文件不包含节标题,也没有标记。
即。
配置部分a 把东西设置成别的东西
config subsection a 把它设置为那个 下一个 结束
配置防火墙策略
编辑76
设置srcintf“那里”
设置dstintf“这里”
设置srcaddr“全部”
设置dstaddr“全部”
设定行动接受
设定时间表“总是”
设置服务“TCP_5600”
下一个 编辑77
设置srcintf“这里”
设置dstintf“那里”
设置srcaddr“全部”
设置dstaddr“全部”
设定行动接受
设定时间表“总是”
设置服务“PING”
下一个 端
由于我无法弄清楚如何让ConfigParser工作,我以为我会尝试迭代文件,不幸的是我没有太多的编程技巧所以我卡住了。 我真的认为我让它变得比它应该更复杂。 这是我写的代码;
class Parser(object):
def __init__(self):
self.config_section = ""
self.config_header = ""
self.section_list = []
self.header_list = []
def parse_config(self, fields): # Create a new section
new_list = []
self.config_section = " ".join(fields)
new_list.append(self.config_section)
if self.section_list: # Create a sub section
self.section_list[-1].append(new_list)
else: self.section_list.append(new_list)
def parse_edit(self, line): # Create a new header
self.config_header = line[0]
self.header_list.append(self.config_header)
self.section_list[-1].append(self.header_list)
def parse_set(self, line): # Key and values
key_value = {}
key = line[0]
values = line[1:]
key_value[key] = values
if self.header_list:
self.header_list.append(key_value)
else: self.section_list[-1].append(key_value)
def parse_next(self, line): # Close the header
self.config_header = []
def parse_end(self, line): # Close the section
self.config_section = []
def parse_file(self, path):
with open(path) as f:
for line in f:
# Clean up the fields and remove unused lines.
fields = line.replace('"', '').strip().split(" ")
if fields[0] == "set":
pass
elif fields[0] == "end":
pass
elif fields[0] == "edit":
pass
elif fields[0] == "config":
pass
elif fields[0] == "next":
pass
else: continue
# fetch and call method.
method = fields[0]
parse_method = "parse_" + method
getattr(Parser, parse_method)(self, fields[1:])
return self.section_list
config = Parser().parse_file('test_config.txt')
print config
我正在寻找的输出类似于以下内容;
[['section a',{'something':'to something else'},['subsection a',{'this':'to that'}]],['防火墙政策',['76 ',{'srcintf':'有'},{'dstintf':'这里'} {等等} {等等}}]]
这就是我得到的
[['section a']]
修改
我已经改变了上述内容以反映我目前的位置。 我仍有问题得到我期望的输出。我似乎无法将清单正确。
答案 0 :(得分:1)
class Parser(object):
def __init__(self):
self.my_section = 0
self.flag_section = False
# ...
def parse_config(self, fields):
self.my_section += 1
# go on with fields
# ...
self.flag_section = True
def parse_edit(self, line):
...
def parse_set(self, line):
...
def parse_end(self, line):
...
def parse_file(self, path):
with open(path) as f:
for line in f:
fields = f.strip().split(" ")
method = fields[0]
# fetch and call method
getattr(Parser, "parse_" + method)(self, fields[1:])
答案 1 :(得分:1)
我为那些在尝试解析Fortigate配置文件时从Google首次来到这里的人发布了我的答案! 我根据自己的需要改写了我在这里找到的东西,并且效果很好。
from collections import defaultdict
from pprint import pprint
import sys
f = lambda: defaultdict(f)
def getFromDict(dataDict, mapList):
return reduce(lambda d, k: d[k], mapList, dataDict)
def setInDict(dataDict, mapList, value):
getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value
class Parser(object):
def __init__(self):
self.config_header = []
self.section_dict = defaultdict(f)
def parse_config(self, fields): # Create a new section
self.config_header.append(" ".join(fields))
def parse_edit(self, line): # Create a new header
self.config_header.append(line[0])
def parse_set(self, line): # Key and values
key = line[0]
values = " ".join(line[1:])
headers= self.config_header+[key]
setInDict(self.section_dict,headers,values)
def parse_next(self, line): # Close the header
self.config_header.pop()
def parse_end(self, line): # Close the section
self.config_header.pop()
def parse_file(self, path):
with open(path) as f:
gen_lines = (line.rstrip() for line in f if line.strip())
for line in gen_lines:
# pprint(dict(self.section_dict))
# Clean up the fields and remove unused lines.
fields = line.replace('"', '').strip().split(" ")
valid_fields= ["set","end","edit","config","next"]
if fields[0] in valid_fields:
method = fields[0]
# fetch and call method
getattr(Parser, "parse_" + method)(self, fields[1:])
return self.section_dict
config = Parser().parse_file('FGT02_20130308.conf')
print config["system admin"]["admin"]["dashboard-tabs"]["1"]["name"]
print config["firewall address"]["ftp.fr.debian.org"]["type"]
答案 2 :(得分:0)
我不知道这是否对你有帮助,但它确实对我有用:http://wiki.python.org/moin/ConfigParserExamples
玩得开心!
答案 3 :(得分:0)
我会以更简单的方式做到这一点:
flagSection = False
flagSub = False
mySection = 0
mySubsection = 0
myItem = 0
with open('d:/config.txt', 'r') as f:
gen_lines = (line.rstrip() for line in f if line.strip())
for line in gen_lines:
if line[0:7]=='config ':
mySection = mySection + 1
newLine = line[7:]
# Create a new section
# Mark section as open
flagSection == True
elif line[0:5]=='edit '):
mySubsection = mySubsection + 1
newLine = line[5:]
# Create a new sub-section
# Mark subsection as open
flagSub == true
elif line[0:4]=='set '):
myItem = myItem + 1
name, value = x.split(' ',2)[1:]
# Add to whatever is open
elif line=='end':
# If subsection = open then close and goto end
if flagSub:
# Or if section = open then close and goto end
elif flagSection:
# :End
continue
指令gen_lines = (line.rstrip() for line in f if line.strip())
创建一个非空行的生成器(感谢测试if line.strip()
),没有换行符,右边没有空格(感谢line.rstrip()
)
如果我想了解您想要使用名称,值以及使用if line=='end'
打开的部分中执行的操作的更多信息,我可以使用正则表达式提出代码。
from time import clock
n = 1000000
print 'Measuring times with clock()'
te = clock()
for i in xrange(n):
x = ('abcdfafdf'[:3] == 'end')
print clock()-te,
print "\tx = ('abcdfafdf'[:3] == 'end')"
te = clock()
for i in xrange(n):
x = 'abcdfafdf'.startswith('end')
print clock()-te,
print "\tx = 'abcdfafdf'.startswith('end')"
print '\nMeasuring times with timeit module'
import timeit
ti = timeit.repeat("x = ('abcdfafdf'[:3] == 'end')",repeat=10,number = n)
print min(ti),
print "\tx = ('abcdfafdf'[:3] == 'end')"
to = timeit.repeat("x = 'abcdfafdf'.startswith('end')",repeat=10,number = n)
print min(to),
print "\tx = 'abcdfafdf'.startswith('end')"
结果:
Measuring times with clock()
0.543445605517 x = ('abcdfafdf'[:3] == 'end')
1.08590449345 x = 'abcdfafdf'.startswith('end')
Measuring times with timeit module
0.294152748464 x = ('abcdfafdf'[:3] == 'end')
0.901923289133 x = 'abcdfafdf'.startswith('end')
timieit 的时间比使用 clock()的时间要小,因为在程序运行时GC已被拔掉?无论如何,使用 clock()或 timeit 模块,执行 startswith()比切片花费更多时间。