Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- How can I extract blocks from this configuration file using Perl?
- pool {
- name "POOL_name1"
- ttl 30
- monitor all "tcp"
- preferred rr
- partition "Common"
- member 12.24.5.100:80
- }
- pool {
- name "Pool-name2"
- ttl 30
- monitor all "https_ignore_dwn"
- preferred rr
- fallback rr
- partition "Common"
- member 69.241.25.121:8443
- member 69.241.25.122:8443
- }
- my @POOLDATA = <FILE>;
- close FILE;
- foreach (@POOLDATA) {
- if (/^pools{s/ .. /^}s/) {
- push (@POOLCONFIG, "$_");
- }
- }
- #!/usr/bin/env perl
- use warnings; use strict;
- my @pools;
- my $keys = join('|', sort
- 'name',
- 'ttl',
- 'monitor all',
- 'preferred',
- 'partition',
- 'member'
- );
- my $pat = qr/^($keys)s+([^n]+)nz/;
- while ( my $line = <DATA> ) {
- if ($line =~ /^pools+{/ ) {
- push @pools, {},
- }
- elsif (my ($key, $value) = ($line =~ $pat)) {
- $value =~ s/^"([^"]+)"z/$1/;
- push @{ $pools[-1]->{$key} }, $value;
- }
- }
- use Data::Dumper;
- print Dumper @pools;
- __DATA__
- pool {
- name "POOL_name1"
- ttl 30
- monitor all "tcp"
- preferred rr
- partition "Common"
- member 12.24.5.100:80
- }
- pool {
- name "Pool-name2"
- ttl 30
- monitor all "https_ignore_dwn"
- preferred rr
- fallback rr
- partition "Common"
- member 69.241.25.121:8443
- member 69.241.25.122:8443
- }
- while ( my $line = <DATA> ) {
- if ($line =~ /^pools+{/ ) {
- push @pools, {},
- }
- elsif (my ($key, $value) = ($line =~ $pat)) {
- $value =~ s/^"([^"]+)"z/$1/;
- push @{ $pools[-1]->{$key} }, $value;
- }
- elsif ($line =~ /^s*}/) {
- my $last = $pools[-1];
- if ($last and not $last->{member}) {
- $last->{member} = [ qw(0.0.0.0) ];
- }
- }
- }
- while ( my $line = <DATA> ) {
- if ($line =~ /^pools+{/ ) {
- push @pools, {},
- }
- elsif (my ($key, $value) = ($line =~ $pat)) {
- $value =~ s/^"([^"]+)"z/$1/;
- push @{ $pools[-1]->{$key} }, $value;
- }
- elsif ($line =~ /^s*}/) {
- my $last = $pools[-1];
- if ($last and not $last->{member}) {
- $last->{member} = [ qw(0.0.0.0) ];
- }
- }
- }
- use strict;
- use warnings;
- use Data::Dumper;
- use English qw<$RS>;
- use List::MoreUtils qw<natatime>;
- use Params::Util qw<_ARRAY _CODE>;
- # Here, we rig the record separator to break on n}n
- local $RS = "n}n";
- # Here, we standardize a behavior with hash duplicate keys
- my $TURN_DUPS_INTO_ARRAYS = sub {
- my ( $hr, $k, $ov, $nv ) = @_;
- if ( _ARRAY( $ov )) {
- push @{ $ov }, $nv;
- }
- else {
- $h->{ $k } = [ $ov, $nv ];
- }
- };
- # Here is a generic hashing routine
- # Most of the work is figuring out how the user wants to store values
- # and deal with duplicates
- sub hash {
- my ( $code, $param_name, $store_op, $on_duplicate );
- while ( my ( $peek ) = @_ ) {
- if ( $code = _CODE( $peek )) {
- last unless $param_name;
- if ( $param_name eq 'on_dup' ) {
- $on_duplicate = shift;
- }
- elsif ( $param_name eq 'store' ) {
- $store_op = shift;
- }
- else {
- last;
- }
- undef $code;
- }
- else {
- my @c = $peek =~ /^-?(on_dup|store$)/;
- last unless $param_name = $c[0];
- shift;
- }
- }
- $store_op ||= sub { $_[0]->{ $_[1] } = $_[3]; };
- $on_duplicate ||= $code || $store_op;
- my %h;
- while ( @_ ) {
- my $k = shift;
- next unless defined( my $v = shift );
- (( exists $h{ $k } and $on_duplicate ) ? $on_duplicate
- : $store_op
- )->( %h, $k, $h{ $k }, $v )
- ;
- }
- return wantarray ? %h : %h;
- }
- my %pools;
- # So the loop is rather small
- while ( <DATA> ) {
- # remove pool { ... } brackets
- s/As*pools+{s*n//smx;
- s/ns*}n*//smx;
- my $h
- = hash( -on_duplicate => $TURN_DUPS_INTO_ARRAYS
- , map { s/"$//; s/s+$//; $_ }
- map { split /s+"|s{2,}/msx, $_, 2 }
- split /n/m
- );
- $pools{ $h->{name} } = $h;
- }
- print Dumper( %pools );
- ### %pools
- __DATA__
- pool {
- name "POOL_name1"
- ttl 30
- monitor all "tcp"
- preferred rr
- partition "Common"
- member 12.24.5.100:80
- }
- pool {
- name "Pool-name2"
- ttl 30
- monitor all "https_ignore_dwn"
- preferred rr
- fallback rr
- partition "Common"
- member 69.241.25.121:8443
- member 69.241.25.122:8443
- }
Add Comment
Please, Sign In to add comment