1

I am trying to figure out how to code the following problem using python. Suppose we have the following data set in a .txt file:

package autoload

config core 'main'
    option Enabled 'no'
    option StartTimer '120'
    option RetryTimer '30'
    option BackoffTimer '15'
    option BootUsingConfig 'altconfig'
    option BootUsingImage 'altimage'

config entry
    option Configured 'yes'
    option SegmentName 'altconfig'
    option RemoteFilename '$$.ini'

package cwatch

config watch '3g_watch'
    option enabled 'yes'
    option test_ifaces 'wan1 wan2'
    option failure_time_1 '30m'
    option failure_action_1 'reboot'

Expecting result as such:

{"autoload":{"core 'main'":{"Enabled": "no", "StartTimer": "120", ...},
             "entry":{"Configure": "yes", "SegmentName": "altconfig", ...},
             ...},
 "cwatch": {"watch '3g_watch'":{"Enabled": "yes", "test_ifaces":"wan1 wan2", ...}}
}

I'm stuck at here and not sure what to do next.

numRegex = re.compile(r'^package (\w*)\s*^config (\w*.*\w*)', re.M)
with open(file) as f:
    data = {m.groups() for m in numRegex.finditer(f.read())}
martineau
  • 119,623
  • 25
  • 170
  • 301
FlyingFox
  • 13
  • 2

2 Answers2

2

Until someone arrives with the regexp-oneliner, I would use an old-school state machine:

bundle = {}
with open("config.txt") as f:
  for line in f:
    line=line.strip().split()
    if line:
      if line[0] == "package":
        package = {}
        bundle[line[1]] = package
      elif line[0] == "config":
        config = {}
        package[" ".join(line[1:])] = config
      elif line[0] == "option":
        config[line[1]] = " ".join(line[2:])
print(bundle)

It results in

{'autoload': {"core 'main'": {'Enabled': "'no'", 'StartTimer': "'120'", 'RetryTimer': "'30'", 'BackoffTimer': "'15'", 'BootUsingConfig': "'altconfig'", 'BootUsingImage': "'altimage'"}, 'entry': {'Configured': "'yes'", 'SegmentName': "'altconfig'", 'RemoteFilename': "'$$.ini'"}}, 'cwatch': {"watch '3g_watch'": {'enabled': "'yes'", 'test_ifaces': "'wan1 wan2'", 'failure_time_1': "'30m'", 'failure_action_1': "'reboot'"}}}

tevemadar
  • 12,389
  • 3
  • 21
  • 49
  • @PatrickArtner thanks! And of course the `if`-s would be nicer with `match`, just it may be too new – tevemadar Jun 23 '21 at 11:25
  • 1
    _Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems._ [[Jamie Zawinsk, ca 1997]] – Patrick Artner Jun 23 '21 at 11:25
0

This sounds very much like a Python configuration file for which you have built-in parsers. Could that do the trick?

bbercz
  • 180
  • 1
  • 11