in reply to searching data lines between keywords

TMTOWTDI, but a longer and less elegant approach:
#!/usr/bin/perl -w use strict; use Data::Dumper; my %hash; my $currentkey; my $inkey = 0; while (<DATA>) { chomp; next if /^\s*$/; # skip blank lines if ($inkey == 0) { $currentkey = $_; $inkey = 1; next; } if (/^\*+END\*+$/) { $inkey = 0; next; } push @{$hash{$currentkey}}, $_; } print Dumper(%hash), $/; __DATA__ mykeyword1 foo1 bar1 ***END*** mykeyword2 ***END*** mykeyword3 baz3 foo3 bar3 ***END*** mykeyword4 baz4 ***END***

Output:

$VAR1 = 'mykeyword3'; $VAR2 = [ 'baz3', 'foo3', 'bar3' ]; $VAR3 = 'mykeyword1'; $VAR4 = [ 'foo1', 'bar1' ]; $VAR5 = 'mykeyword4'; $VAR6 = [ 'baz4' ];

Lupey

Replies are listed 'Best First'.
Re^2: searching data lines between keywords
by kaif (Friar) on Jun 14, 2005 at 15:37 UTC

    Where did keyword2 go? Perhaps this was a design decision. If not, adding the line @{$hash{$currentkey}} = (); into the if( $inkey == 0 ) block does the trick.

    P.S.: In order to make Data::Dumper print very nice output, pass it a hash reference, as in Dumper(\%hash). Then the output is as follows:

    $VAR1 = { 'mykeyword3' => [ 'baz3', 'foo3', 'bar3' ], 'mykeyword2' => [], 'mykeyword1' => [ 'foo1', 'bar1' ], 'mykeyword4' => [ 'baz4' ] };

    P.P.S.: Can some enlightened monk tell me the preferred way to "touch" an array (reference). That is, if I only want to clear an array if it doesn't already exist (see my @{$hash{$currentkey}} = (); addition above). The snippet push @{$hash{$currentkey}}; works but produces a Useless use of push with no values warning.

      P.P.S.: Can some enlightened monk tell me the preferred way to "touch" an array (reference). That is, if I only want to clear an array if it doesn't already exist (see my @{$hash{$currentkey}} = (); addition above). The snippet push @{$hash{$currentkey}}; works but produces a Useless use of push with no values warning.

      I typically use:

      $hash{$currentkey} ||= [];

      Which will set it to an empty array ref, if it isn't already a 'true' value, and undefined isn't true ... of course, there's lots of other not true values, as well (empty string, 0, etc.)

      @{$hash{$currentkey}} is an array so you can truncate the array just as you would any other array. You don't need to use push. Both of these will do the trick

      @{$hash{$currentkey}} = (); $#{$hash{$currentkey}} = -1;

      Lupey

        I would like to create the array if it doesn't exist and not do anything otherwise. This is similar to the touch command in Unix-like environments. The command push @{$ref}; does exactly that: it pushes nothing onto the array, which creates it if necessary but doesn't change it if it exists.