

以下のようなテキストファイルを、シェルスクリプトにてCSVファイル形式に加工したいと考えています。  
Linux上で加工出来れば、手法については拘りはありません。  
実現方法が思いつかない為、アドバイス等を頂けると助かります。

・テキストファイル

[code]

    ltm virtual /Common/vip-A {
        destination /Common/192.168.1.1:80
        ip-protocol tcp
        mask 255.255.255.255
        pool /Common/pool-A
        profiles {
            /Common/fastl4_default { }
        }
        source 0.0.0.0/0
        translate-address enabled
        translate-port enabled
    }
    ltm virtual /Common/vip-B {
        destination /Common/192.168.1.2:80
        ip-protocol tcp
        mask 255.255.255.255
        pool /Common/pool-B
        profiles {
            /Common/clientssl-www.hoge.jp {
                context clientside
            }
            /Common/tcp { }
        }
        source 0.0.0.0/0
        translate-address enabled
        translate-port enabled
    }
    ltm pool /Common/pool-A {
        members {
            /Common/192.168.2.1:80 {
                address 192.168.2.1
            }
        }
        monitor /Common/tcp 
    }
    ltm pool /Common/pool-B {
        members {
            /Common/192.168.2.2:80 {
                address 192.168.2.2
            }
        }
        monitor /Common/tcp 
    }
    
[/code]

・CSV出力例

[code]

    vip-A,192.168.1.1:80,tcp,255.255.255.255,pool-A,fastl4_default,0.0.0.0/0,enabled,enabled
    vip-B,192.168.1.2:80,tcp,255.255.255.255,pool-B,www.hoge.jp,0.0.0.0/0,enabled,enabled
    pool-A,192.168.1.1:80,192.168.2.1,tcp
    pool-B,192.168.1.2:80,192.168.2.2,tcp
    
[/code]

補足になります。  
・実機の設定ファイルを、一覧表で管理するのが目的で進めています。  
・階層構造の形式で、括弧でくくられた1つの塊を1行にしたいのですが、  
awkコマンドで抽出することを思いついたのですが、改行の条件をどうしたら良いのかで悩んでいます。


CC BY-SA 4.0
2018-11-02T04:28:18.567
49883
2019-10-29T11:43:52.713
30809
question
linux shellscript sh awk
階層構造の文字列を抽出する方法について


方針だけ。。

多分、今回のケースに一番適しているのは perl6 の grammer を用いることではないかなと思っています。

ただ、自分は perl を記述したことがないので、フルの回答は作成できなさそうだ、と思っています。


CC BY-SA 4.0
2018-11-02T21:46:38.123
49909
2018-11-02T21:46:38.123
754
49883
answer


`}`だけの行を終端とし、終端の行以外の改行コードを`,`に置換すればよいと思います。

[code]

    sed 's/^}$/}^D/' | tr '\n' '^E' | tr '^D' '\n' | tr '^E' ',' | sed 's/^,//'
    
[/code]

^Dや^Eは制御文字です。入力に出現しない文字ならなんでもいいです。  
以下実行結果です。不要な情報の削除はしてません。  
「階層構造の形式で、括弧でくくられた1つの塊を1行にした」だけです。

[code]

    ltm virtual /Common/vip-A {,    destination /Common/192.168.1.1:80,    ip-protocol tcp,    mask 255.255.255.255,    pool /Common/pool-A,    profiles {,        /Common/fastl4_default { },    },    source 0.0.0.0/0,    translate-address enabled,    translate-port enabled,}
    ltm virtual /Common/vip-B {,    destination /Common/192.168.1.2:80,    ip-protocol tcp,    mask 255.255.255.255,    pool /Common/pool-B,    profiles {,        /Common/clientssl-www.hoge.jp {,            context clientside,        },        /Common/tcp { },    },    source 0.0.0.0/0,    translate-address enabled,    translate-port enabled,}
    ltm pool /Common/pool-A {,    members {,        /Common/192.168.2.1:80 {,            address 192.168.2.1,        },    },    monitor /Common/tcp ,}
    ltm pool /Common/pool-B {,    members {,        /Common/192.168.2.2:80 {,            address 192.168.2.2,        },    },    monitor /Common/tcp ,}
    
[/code]


CC BY-SA 4.0
2019-08-28T17:10:23.227
57664
2019-08-28T17:10:23.227
35558
49883
answer


_本当に_ _本当に_ _本当に_ 汚いワンライナーでよければこんな感じになるけど・・・

[code]

    $ cat /tmp/bigip.conf | perl -nE '($w) = $_ =~ m!^.*\s(?:/.*/)?([^{}\s]+)!; if (/^}\s*$/) { say join ",", grep { length } @buf; @buf = () } elsif (/^\s*[a-z]+\s*\{\s*$/) { next } else { push @buf, $w }'
    vip-A,192.168.1.1:80,tcp,255.255.255.255,pool-A,fastl4_default,0.0.0.0/0,enabled,enabled
    vip-B,192.168.1.2:80,tcp,255.255.255.255,pool-B,clientssl-www.hoge.jp,clientside,tcp,0.0.0.0/0,enabled,enabled
    pool-A,192.168.2.1:80,192.168.2.1,tcp
    pool-B,192.168.2.2:80,192.168.2.2,tcp
    
[/code]


CC BY-SA 4.0
2019-10-29T11:43:52.713
60085
2019-10-29T11:43:52.713
62
49883
answer