1

非常に長い間引き出された質問に対するお詫び。

設定ファイルを読み込んで、ルールのリストを取得しようとしています。ConfigParserを使用してこれを実行しようとしましたが、標準の構成ファイルではありません。このファイルには、セクションヘッダーとトークンは含まれていません。

すなわち

configセクションa
何かを他の何かに設定します
configサブセクションa
これをその
次の
終わりに設定します

configファイアウォールポリシー
編集
76setsrcintf "There"
set dstintf "Here"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "TCP_5600"
next
edit 77
set srcintf "here"
set dstintf "there "
set srcaddr" all "
set dstaddr" all "
set action accept
set schedule" always "
set service" PING "
next
end

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'}、['subsection a'、{'this':'to that'}]]、['firewall policy'、['76'、{ 'srcintf':'There'}、{'dstintf':'Here'}{etc。}{etc。}]]]

これが私が得たものです

[['セクションa']]

編集

私は現在の場所を反映するために上記を変更しました。期待する出力を得るのにまだ問題があります。私はリストを正しく理解できないようです。

4

4 に答える 4

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:])
于 2011-09-26T08:46:02.460 に答える
0

これがあなたにも役立つかどうかはわかりませんが、私にとっては役に立ちました:http ://wiki.python.org/moin/ConfigParserExamples

楽しむ !

于 2011-09-26T08:48:58.280 に答える
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()) は、空でない行のジェネレーターを作成します ( test のおかげで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')

プログラムの実行時にGCが取り外されているため、timeeitの方がclock()よりも時間が小さいという事実はありますか? とにかく、clock()またはtimeitモジュールのいずれかを使用すると、 startswith()の実行はスライスよりも時間がかかります。

于 2011-09-26T09:20:19.577 に答える