quasimojo has asked for the wisdom of the Perl Monks concerning the following question:

Hello everyone,

If I have a file in which I am searching for any line beginning with "Open Square Bracket" and ending with "Close Square Bracket" and then saving all such matching lines in an Array called @BROKERS. How would I tell perl to go through the file again, matching on each element of @Brokers, and then after it found a line that matched that element push each subsidiary line that followed into an array named $BROKER[x] until a blank line is reached. At this point the loop should continue to the next element of @BROKERS and repeat the above proccess until there are no elements left.

I am very new to perl and languages in general so please excusive the crudity of the code I have written so far.

#!/usr/bin/perl -w # my @BROKERS; open (CONFIG, "ubroker.properties") || die "Can't Open ubroker file: $ +!"; while (<CONFIG>) { next if /^#/; if (/^\[UBroker\.WS\./) { push (@BROKERS,$_); } } chomp @BROKERS; while (<CONFIG>) { foreach $b(@BROKERS) { if (/$b/) { # Here is where I run out of steam # Begin Metacode read each line and push ($_,@"$b") continue to do this until + a newline is reached. When a newline is reached intialize the next +$b as an array and repeat the above proccess until all elements of @B +ROKERS are exhausted.

I hope the question ain't to crude, if it is I'll be glad to expand on it!
Thanks!
Pat

Edit by tye

Replies are listed 'Best First'.
Re: Appropriate application of readline
by blakem (Monsignor) on Sep 26, 2001 at 23:34 UTC
    It seems like you should be using a slightly different datastructure for this. A hash of arrays (HoA) would fit nicely... The hash is keyed on the broker's name and the values are arrays containing the matching lines. Something like this:
    #!/usr/bin/perl -wT use strict; my @brokerlist = qw(broknum1 broknum2 broknum3); # array of brokers my $pattern = join('|',@brokerlist); # create a ORed regex of the b +rokers my %brokers; # will become a hash of arrays, keyed on broker nam +e while(<DATA>) { chomp; # if the line matches push it onto appropriate array push(@{$brokers{$1}},$_ ) if /\b($pattern)\b/o; } ### print out the datastructure to make sure it is correct for my $broker (keys %brokers) { print "$broker\n"; print "\t$_\n" for (@{$brokers{$broker}}); } =OUTPUT broknum2 broknum2 is my favorite broker broknum3 i am a broknum3 client my uncle is broknum3 broknum1 this line if for broknum1 broknum1 is a fool =cut __DATA__ this line if for broknum1 i am a broknum3 client broknum2 is my favorite broker broknum1 is a fool my uncle is broknum3

    -Blake

      Thanks for the reply's everbody!!!
      While I was waiting for some answers I decided to forge on by myself. Obviously the ideas you guys gave me are better, and I will be incorporating them into my current code. For posterity though here is how I worked around:
      #!/usr/bin/perl -w # my @BROKERS; open (CONFIG, "ubroker.properties") || die "Can't Open ubroker file: $ +!"; while (<CONFIG>) { $/=""; next if /^#/; if (/^\[UBroker\.WS\./) { push (@BROKERS,$_); } } #chomp @BROKERS; @FIRST=split(/\s+/,$BROKERS[1]); #@SECOND=split(/\s+/,$BROKERS[2]); #@THIRD=split(/\s+/,$BROKERS[3]); #@FOURTH=split(/\s+/,$BROKERS[4]);; foreach $i(@FIRST) { if ($i =~ /^initialSrvrInstance/i) { $max= $i; print "$max\n"; } } close (CONFIG) || die "Can't Close ubroker file: $!"; exit 0;

      But like you said I really like the entire hash approach better then what I am doing now!!!
      Thanks for the Help!
      Pat+
Re: Appropriate application of readline
by tachyon (Chancellor) on Sep 26, 2001 at 23:14 UTC

    You would probably be best to use a hash where the key is the broker you find and the values is the data. Here is an example:

    #!/usr/bin/perl -w use strict; my (%brokers, $broker); # get file contents into an array for convenience open (CONFIG, "ubroker.properties") || die "Can't Open ubroker file: $ +!"; while (<CONFIG>) { next if /^#/; chomp; $broker = $_ if /^\[.*\]$/; # found a broker $broker = '' if /^\s*$/; # found a blank line # add line to current $broker if there is one $brokers{$broker} .= "$_\n" if $broker; } close CONFIG; # keys %brokers returns an array of brokers to iterate over for (keys %brokers) { print "\nBroker: $_\n"; # this is the broker name print $brokers{$_}; # this is the data (includes name) }

    If you want to do it with a while(<CONFIG>) you either need to do it in one loop (as you will reach the end of the file after the first loop) or use seek CONFIG, 0, 0; to go back to the begining of the file before you do a second while loop through it.

    In this example we use a hash to store both the brokers array (as the keys) and the data associated with each broker (as the values) which means that there is a logical link between the data. If you just wanted arrays then:

    @brokers = keys %brokers; @data = values %brokers;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print