首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl模块还是获取嵌套大括号中数据的方法?

Perl模块还是获取嵌套大括号中数据的方法?
EN

Stack Overflow用户
提问于 2017-06-06 20:48:43
回答 1查看 212关注 0票数 1

我有一些配置文件(实际上是从防火墙报告导出的),使用这种结构:

代码语言:javascript
复制
 policies {
        apply-groups default-log;
        from-zone Trust to-zone DMZ {
            policy policy-66 {
                match {
                    source-address g_DMZ_SRV_;
                    destination-address g_DMZ_SRV;
                    application any;
                }
                then {
                    permit;
                }
            }
            policy policy-9 {
                match {
                    source-address g_h_OpenMail-Server;
                    destination-address g_in_DMZ_Exchange;
                    application t_1023;
                }
                then {
                    permit;
                }
            }
        }
        from-zone DMZ to-zone Blabla {
            policy policy-68 {
                match {
                    source-address g_DMZ_SRV_2_;
                    destination-address g_DMZ_SRV_3;
                    application T_22-ssh;
                }
                then {
                    permit;
                }
            }
            policy policy-95 {
                match {
                    source-address g_h_OpenMail-Server-2;
                    source-address 1.2.0.3;
                    destination-address g_in_DMZ_Exchange-1;
                    destination-address 10.25.32.64;
                    application t_1024;
                }
                then {
                    permit;
                }
            }
        }

}

我想在Perl中解析它,以便构建一个哈希(例如,或者简单地提出处理数据的条件),然后我可以利用它,例如:

代码语言:javascript
复制
Trust-to-DMZ
      policy-66
            source => g_DMZ_SRV
            destination => blabla
      policy-44
            source => source1
                      source2
                      source3
            destination => dest1
            ports => port1
DMZ-to-Trust
      policy-XX

我想知道:

  1. 如果您知道一些模块在这样的任务中有帮助(我想我可以使用Text::Balanced,我在其他几篇文章中找到了一些例子)
  2. 这样做是否有一些方法/最佳做法来避免肮脏的工作?

我想我可以“数数”大括号的数目,并在循环中做循环。但那会很脏。

难道没有更简单的解决方案或模块自动完成此操作吗?(就像存在于XML文件的模块-例如, XML::Simple将XML的内容放入哈希中,- ?)

否则,我将开始编写一些肮脏的代码,并在这里发布我的进度

谢谢!

在6月8日编辑,就像你知道的那样,它与这样的脏代码一起工作(抱歉,我不是开发人员),这不是我想要的,因为它没有适应性。显然你已经被警告过了!:)所以如果你不想在眼睛里流血的话,就不要看它!

代码语言:javascript
复制
use warnings;
use lib '/opt/csm/64-bit/cpan/5.16.3-2013.03/lib';
use Data::Dumper;

my ( $policies_flag, $fromzone_flag, $policy_flag, $match_flag, $zone_flag ) = ( 0,0,0,0,0 );
my ( $details_flag, $clos_flag, $then_flag, $permit_flag, $clos2_flag, $final_flag ) = ( 0,0,0,0,0,0 );

my $fromzone;
my $tozone;

my %pols;
my $clos_counter;

die "Usage: $0 <path_to_file>" if $ARGV[0] eq '';

open D, '<', $ARGV[0] or die "cannot open $ARGV[0] for read\n";
@data = <D>;
close D;


OUTER: foreach my $str (@data) {

     next if $str =~ /^$/;
     next if $str =~ /apply-groups/;
     chomp $str;

if ( $str =~ /\s*policies\s+\{/ ) {
        $policies_flag = 1;
        next OUTER;
}


# policies
if ($policies_flag == 1) {

    if ($str =~ /from-zone\s\S+\sto-zone\s\S+\s\{$/) {
        next if $str =~ /(<|>)/;
        ( $fromzone, $tozone ) = ( split(/\s+/,$str) )[2,4];
        $fromzone_flag = 1;
        next OUTER;
    }

    # from-zone
    if ($fromzone_flag == 1) {

        if ($str =~ /policy\s+\S+\s+\{/) {
            $policy_flag = 1;
            $clos_counter=0;
            ( $policy_name ) = ( split(/\s+/, $str) )[2];
            $pols{$policy_name}{from_zone} = "$fromzone";
            $pols{$policy_name}{to_zone} = "$tozone";
            next OUTER;
        }

        # pol
        if ($policy_flag == 1) {

            if ($str =~ /match\s+\{/) {
                $match_flag = 1;
                next OUTER;
            }

        }

        # match
        if ($match_flag == 1) {

            if ($str =~ /\S+\s+\S+;$/) {
                $details_flag = 1;

                if ($str =~ /source-address/) {
                    ( $sources ) = ( split(/\s+/, $str) )[2];
                    $sources =~ s/;//;
                    push( @{$pols{$policy_name}{sources}}, "$sources");
                } elsif ($str =~ /destination-address/) {
                    ( $dests ) = ( split(/\s+/, $str) )[2];
                    $dests =~ s/;//;
                    push( @{$pols{$policy_name}{destinations}}, "$dests");
                } elsif ($str =~ /application/) {
                    ( $ports ) = ( split(/\s+/, $str) )[2];
                    $ports =~ s/;//;
                    push( @{$pols{$policy_name}{ports}}, "$ports");
                }

                next OUTER;
            }

        }

        # rest
        if ($details_flag == 1) {

            if ($str =~ /\s*\}\s*$/) {
                if ($clos_counter == 0) {
                    $clos_flag = 1;
                    $clos_counter++;
                    next OUTER;
                }
            }

        }

        # then
        if ($clos_flag == 1) {

            if ($str =~ /\s*then\s+\{$/) {
                $then_flag = 1;
                next OUTER;
            }

        }

        # permit
        if ($then_flag == 1) {

            if ($str =~ /\s*permit;$/) {
                $permit_flag = 1;
                $pols{$policy_name}{action} = ( split(/\s+/,$str) )[1];
                next OUTER;
            }

        }

        # clos2
        if ($permit_flag == 1) {

            if ($str =~ /\s*\}\s*$/) {
                if ($clos_counter == 1) {
                    $clos2_flag = 1;
                    $clos_counter++;
                    next OUTER;
                }
            }

        }

        # final close
        if ($clos2_flag == 1) {

            if ($str =~ /\s*\}\s*$/) {
                if ($clos_counter == 2) {
                    $final_flag = 1;
                    $clos_counter++;
                    next OUTER;
                }
            }

        }

        # ultimate zone
        if ($final_flag == 1) {

            if ($str =~ /\s*\}\s*$/) {
                if ($clos_counter == 3) {
                    $zone_flag = 1;
                    $clos_counter++;
                    next OUTER;
                }
            }

        }

        # ulti pols
        if ($zone_flag == 1) {

            if ($str =~ /\s*\}\s*$/) {
                if ($clos_counter == 4) {
                    $clos_counter++;
                    last OUTER;
                }
            }

        }


    }

}

}

print Dumper(\%pols);

这意味着:

代码语言:javascript
复制
$VAR1 = {
      'policy-68' => {
                       'ports' => [
                                    'T_22-ssh'
                                  ],
                       'sources' => [
                                      'g_DMZ_SRV_2_'
                                    ],
                       'to_zone' => 'Blabla',
                       'from_zone' => 'DMZ',
                       'action' => 'permit;',
                       'destinations' => [
                                           'g_DMZ_SRV_3'
                                         ]
                     },
      'policy-9' => {
                      'ports' => [
                                   't_1023'
                                 ],
                      'sources' => [
                                     'g_h_OpenMail-Server'
                                   ],
                      'to_zone' => 'DMZ',
                      'from_zone' => 'Trust',
                      'action' => 'permit;',
                      'destinations' => [
                                          'g_in_DMZ_Exchange'
                                        ]
                    },
      'policy-66' => {
                       'ports' => [
                                    'any'
                                  ],
                       'sources' => [
                                      'g_DMZ_SRV_'
                                    ],
                       'to_zone' => 'DMZ',
                       'from_zone' => 'Trust',
                       'action' => 'permit;',
                       'destinations' => [
                                           'g_DMZ_SRV'
                                         ]
                     },
      'policy-95' => {
                       'ports' => [
                                    't_1024'
                                  ],
                       'sources' => [
                                      'g_h_OpenMail-Server-2',
                                      '1.2.0.3'
                                    ],
                       'to_zone' => 'Blabla',
                       'from_zone' => 'DMZ',
                       'action' => 'permit;',
                       'destinations' => [
                                           'g_in_DMZ_Exchange-1',
                                           '10.25.32.64'
                                         ]
                     }
    };
EN

回答 1

Stack Overflow用户

发布于 2017-06-14 16:59:19

在我看来,Marpa::R2可能不是完全没有偏见的,它是解决您的问题的好方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44399580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档