pythonarraysbashlexical-analysisshlex

How to parse bash array using Python shlex?


Input:

declare -a ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")

Desired output

And I would like to get this output:

{
    'ForwardPort': [ 
        '"L *:9102:10.0.1.8:9100 # remote laptop"', 
        '"L *:9166:8.8.8.8:9100 # google"'
        ]
}

Attempt

I tried to play a bit with shlex, but the parsing of the array is terrible:

import shlex
line='ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")'
lex=shlex.shlex(line)
list(lex)
['ForwardPort', '=', '(', '[', '0', ']', '=', '"L *:9102:10.0.1.8:9100 # remote laptop"', '[', '1', ']', '=', '"L *:9166:8.8.8.8:9100 # google"', ')']

Question

Is there a way to automatically parse the value of ForwardPort into a list?

N.B.: Don't reproduce at home it was a bad design decision that lead to this convoluted problem :S


Solution

  • you could print that out in bash with:

    #!/bin/bash
    
    declare -a ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")
    res=$(python -c 'import json, sys; print(json.dumps({"ForwardPort": [v for v in sys.argv[1:]]}))' "${ForwardPort[@]}")
    echo "$res"
    

    gives:

    {"ForwardPort": ["L *:9102:10.0.1.8:9100 # remote laptop", "L *:9166:8.8.8.8:9100 # google"]}
    

    if you have that bash array definition as string in python, you could try this somewhat crude parsing:

    import re
    
    line='ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")'
    
    name, arr = line.split('=(')
    arr = arr[:-1]  # removing the trailing ')'
    lst = [item for item in re.split('\[\d+\]=', arr) if item]
    
    dct = {name: lst}
    print(dct)