in reply to how to remove matched multi lines

Other specific solutions are great. But I got onto a different track as I think the idea of the range ... operator is a good one as this leads to a general solution that can be used to sort the input records by some arbitrary input criteria, etc. The idea being to make an Array of Hash and then process that...

I got this far with some code. It works fine except for some reason, this code requires a "blank line" between the define {....} records otherwise a record gets missed in the final array. I appear to be in some sort of "brain lock" right now! The solution has to be simple, and I've gotten some hints, but I'm not able to see it! Oh, yes I do know that my deleteDB() sub isn't the fastest critter on the block.

define host{ use windows-server .... } define host{ use windows-server } is ok, BUT define host{ use windows-server .... } define host{ use windows-server } is not ok!
#!usr/bin/perl -w use strict; use Data::Dumper; my @DB; my %hash = (); while (<DATA>) { if ( m/^define/.../}\s*$/) { next if /{\s*$/; next if /\s*\}\s*/; my ($hkey,$hval) = split; $hash{$hkey}=$hval; } else { push @DB, {%hash}; } } push @DB,{%hash}; print Dumper \@DB; #Array of Hash has been created deleteDB ('address' => '192.168.1.1'); #delete one record sub deleteDB { my ($key,$value) = @_; @DB = grep {$_->{"$key"} ne "$value"} @DB; } print "=============================\n"; print Dumper \@DB; #Prints: #$VAR1 = [ # { # 'use' => 'windows-server', # 'hostgroups' => '060202', # 'host_name' => 'serverA', # 'address' => '192.168.1.1', # 'alias' => '060202', # 'contact_groups' => 'yu' # }, # { # 'use' => 'windows-server', # 'hostgroups' => '060202', # 'host_name' => 'serverA', # 'address' => '192.168.1.11', # 'alias' => '060202', # 'contact_groups' => 'yu' # }, # { # 'use' => 'windows-server', # 'hostgroups' => '060202', # 'host_name' => 'serverA', # 'address' => '192.168.1.21', # 'alias' => '060202', # 'contact_groups' => 'yu' # } # ]; #============================= #$VAR1 = [ # { # 'use' => 'windows-server', # 'hostgroups' => '060202', # 'host_name' => 'serverA', # 'address' => '192.168.1.11', # 'alias' => '060202', # 'contact_groups' => 'yu' # }, # { # 'use' => 'windows-server', # 'hostgroups' => '060202', # 'host_name' => 'serverA', # 'address' => '192.168.1.21', # 'alias' => '060202', # 'contact_groups' => 'yu' # } # ]; __DATA__ define host{ use windows-server host_name serverA hostgroups 060202 alias 060202 contact_groups yu address 192.168.1.1 } define host{ use windows-server host_name serverA hostgroups 060202 alias 060202 contact_groups yu address 192.168.1.11 } define host{ use windows-server host_name serverA hostgroups 060202 alias 060202 contact_groups yu address 192.168.1.21 }

Replies are listed 'Best First'.
Re^2: how to remove matched multi lines
by GrandFather (Saint) on Jul 28, 2009 at 20:51 UTC

    It is instructive to look at what the flip-flop operator actually generates. Consider:

    use strict; use warnings; my $str = '[][ab]c[]d'; for my $chr (split '', $str) { my $result = $chr eq '[' .. $chr eq ']'; printf "%-2s %s\n", $chr, $result; }

    Prints:

    [ 1 ] 2E0 [ 1 a 2 b 3 ] 4E0 c [ 1 ] 2E0 d

    Note the iteration count for 'true' and that the last iteration has a trailing 'E0'. Your 'missing blank line' problem is just like the '][' case above - you need to either retest the ending condition and exclude it, or you can save the flip-flop result and test that.

    If you haven't seen it already, you may find Flipin good, or a total flop? of interest too.


    True laziness is hard work