Perl模块或方法来抓取嵌套大括号内的数据?
问题描述:
我一直在使用那种结构的(从事实上防火墙报告出口)一些配置文件:Perl模块或方法来抓取嵌套大括号内的数据?
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,以建立例如哈希(或简单地说条件处理的数据),我可以事后利用,比如像:
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
我想要想知道:
,如果你知道一些模块在这样的任务帮助(我想我可以使用文本::平衡,我发现在其他几个职位的一些例子)
如果有这样做的一些方法/最佳做法,以避免肮脏的工作?
我想我可以“计数”大括号的数量,并在循环中做循环..但它会很脏。
是不是有一个更简单的解决方案或模块自动执行此操作? (如模块存在,例如XML文件,XML ::简单把一个XML的内容到一个哈希,我会期待那种东西类似的东西?)
否则我将开始编码脏东西,并在这里发布我的进度
谢谢!
编辑于6月8日,只是让你知道,它的工作原理用脏脏脏的代码一样,(我不是一个开发商,道歉),这是不是真的我想要的,因为它不是适应..并显然肮脏地狱 你已被警告! :)所以不要看它,如果你不你的眼睛要血
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);
这给:
$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'
]
}
};
答
的马尔巴社会的罗恩·萨维奇想出了以下内容:
my($parser) = Text::Balanced::Marpa -> new ( open => ['{'], close => ['}'], ); my($text) = read_text('policies.txt'); my($result) = $parser -> parse(text => \$text); print "Parse result: $result (0 is success)\n"; #print join("\n", @{$parser -> tree -> tree2string}), "\n"; my($indent); for my $node ($parser -> tree -> traverse($parser -> tree -> POST_ORDER)) { $indent = ' ' x $node -> depth; $text = ${$node -> meta}{text} =~ s/\n|[{}]//gr; say $indent, $text if ($text); }
Output:
Parse result: 0 (0 is success)
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;
This gist包含上面的代码和输出。 Stackoverflow的格式化程序坚持要缩进所有的东西,不管它是否理解 - 可以依靠这个要点来包含一个预损坏的副本。
这听起来像是我的一个马尔帕任务。但是我必须阅读大量的文档才能构建它。 – simbabque
你在说Marpa :: R2吗?不用担心,我不希望人们代码而不是我编写代码,只是想知道是否有人已经这样做了,并且如果模块确实存在以便做到“简单”(就像XML :: Simple对XML文件所做的一样成哈希例如),我会看看马尔帕,感谢您的提示! – olivierg
什么工具准确地产生这个输出?也许有什么关于cpan的?如果没有,建立它并把它放在那里。 – simbabque