yeah, i didn't read the sample output..... so, here ya go.
On Sun, Apr 3, 2011 at 6:06 PM, Rob Dixon <[email protected]> wrote:
> On 03/04/2011 18:05, Wernher Eksteen wrote:
>> Got this to work, but is there a better way to do this?
>>
>> #!/usr/bin/perl
>>
>> use strict;
>> use warnings;
>>
>> my ( $val, @matched, @unmatched, %hash1, %hash2 );
>>
>> %hash1 = (
>> "emcpowera" => "sdbd sddg sdfj sdhm",
>> "emcpoweraa" => "sdae sdch sdek sdgn",
>> "emcpowerbc" => "sdb sdbe sddh sdfk",
>> "emcpowerc" => "sdbb sdde sdfh sdhk",
>> "emcpowerd" => "sdba sddd sdfg sdhj",
>> "emcpowerz" => "sdba sddd sdfg sdhj"
>> );
>>
>> %hash2 = (
>> "emcpowera1" => "/dwpdb006",
>> "emcpoweraa1" => "/dwpdb033",
>> "emcpowerbc1" => "/s00_11",
>> "emcpowerbc2" => "/utl_file_dir",
>> "emcpowerc1" => "/odsdb006",
>> "emcpowerd1" => "/odsdb005"
>> );
>>
>> foreach my $i (keys(%hash1)) {
>>
>> foreach my $b (keys(%hash2)) {
>>
>> if ($b =~ /$i[0-9]+/) {
>> $val = $b;
^^ will error with strict vars. use: my $val = $b;
>> push @matched, "$i" . " $hash1{$i} " . "$b" . "
>> $hash2{$b} " . "\n";
>> }
>> }
>>
>> if (not $i =~ /$val*/) {
how about: if( $i !~ /$val*/ )
but, i would keep my logic the same.
>> push @unmatched, "$i" . " $hash1{$i} " . "\n";
>> }
>> }
>>
>> print " @matched";
>> print " @unmatched\n";
>>
>> --- RESULT ---
>>
>> emcpoweraa sdae sdch sdek sdgn emcpoweraa1 /dwpdb033
>> emcpowerd sdba sddd sdfg sdhj emcpowerd1 /odsdb005
>> emcpowerc sdbb sdde sdfh sdhk emcpowerc1 /odsdb006
>> emcpowerbc sdb sdbe sddh sdfk emcpowerbc1 /s00_11
>> emcpowerbc sdb sdbe sddh sdfk emcpowerbc2 /utl_file_dir
>> emcpowera sdbd sddg sdfj sdhm emcpowera1 /dwpdb006
>> emcpowerz sdba sddd sdfg sdhj
>
> I suggest you reduce your tab size from eight characters, which leave
> your code spread out and less readable. Four or two is more usual
> nowadays.
agreed, if you do this and you go 4 or more layers deep, you'll be
half way across the page with a tabstep like that.
>
> Meaningful variable names are also important. Using $i as the key to
> %hash1 and $b as the key to %hash2 is a very bad idea: both have
> different conventional uses and $b is a special variable used internally
> by Perl.
>
> Long chains of concatenated strings can be improved visually by
> interpolation:
>
> push @matched, "$i $hash1{$i} $b $hash2{$b}\n";
>
> or formatting:
>
> push @matched, sprintf "%s %s %s %s\n", $i, $hash1{$i}, $b, $hash2{$b};
>
> As for an improved version, your main purpose seems to be to combine
> data that belongs under the same /emcpower.*/ prefix. The program below
> does this by modifying %hash1, rather than building two new arrays as
> yours does. If this is unacceptable then come back to us.
>
> The program iterates over the records in %hash2, removes the decimals
> from the end of the key, and uses the result to select the record in
> %hash1 that should be appended to.
>
> HTH,
>
> Rob
>
>
>
> use strict;
> use warnings;
>
> my %hash1 = (
> emcpowera => "sdbd sddg sdfj sdhm",
> emcpoweraa => "sdae sdch sdek sdgn",
> emcpowerbc => "sdb sdbe sddh sdfk",
> emcpowerc => "sdbb sdde sdfh sdhk",
> emcpowerd => "sdba sddd sdfg sdhj",
> emcpowerz => "sdba sddd sdfg sdhj",
> );
>
> my %hash2 = (
> emcpowera1 => "/dwpdb006",
> emcpoweraa1 => "/dwpdb033",
> emcpowerbc1 => "/s00_11",
> emcpowerbc2 => "/utl_file_dir",
> emcpowerc1 => "/odsdb006",
> emcpowerd1 => "/odsdb005",
> );
>
> for my $key2 (keys %hash2) {
> (my $key1 = $key2) =~ s/\d+\z//;
> if ($hash1{$key1}) {
> $hash1{$key1} = "$hash1{$key1} $key2 $hash2{$key2}";
> }
> }
>
> foreach my $key1 (sort keys %hash1) {
> print "$key1 $hash1{$key1}\n";
> }
>
> **OUTPUT**
>
> emcpowera sdbd sddg sdfj sdhm emcpowera1 /dwpdb006
> emcpoweraa sdae sdch sdek sdgn emcpoweraa1 /dwpdb033
> emcpowerbc sdb sdbe sddh sdfk emcpowerbc1 /s00_11 emcpowerbc2 /utl_file_dir
> emcpowerc sdbb sdde sdfh sdhk emcpowerc1 /odsdb006
> emcpowerd sdba sddd sdfg sdhj emcpowerd1 /odsdb005
> emcpowerz sdba sddd sdfg sdhj
>
>
^^^^ that's shorter and requires less horsepower, but here it is with
new hashes (debugged this time :) ). note, the hashes don't print
separated, you can define an array (as you've already demonstrated) or
loop through them and print each key / val that way (as i've
demonstrated).
#!/usr/bin/perl
use strict;
use warnings;
my %hash1 = (
"emcpowera" => "sdbd sddg sdfj sdhm",
"emcpoweraa" => "sdae sdch sdek sdgn",
"emcpowerbc" => "sdb sdbe sddh sdfk",
"emcpowerc" => "sdbb sdde sdfh sdhk",
"emcpowerd" => "sdba sddd sdfg sdhj",
"emcpowerz" => "sdba sddd sdfg sdhj"
);
my %hash2 = (
"emcpowera1" => "/dwpdb006",
"emcpoweraa1" => "/dwpdb033",
"emcpowerbc1" => "/s00_11",
"emcpowerbc2" => "/utl_file_dir",
"emcpowerc1" => "/odsdb006",
"emcpowerd1" => "/odsdb005"
);
print "Hash1: ", %hash1, "\n";
print "Hash2: ", %hash2, "\n";
my( %hash3, %nothash );
my $found = 0;
while( my( $ikey, $ival ) = each( %hash1 ) ) {
print "1: $ikey => $ival\n";
while( my( $jkey, $jval ) = each( %hash2 ) ) {
(my $mkey = $jkey ) =~ s/[0-9]//g;
print "2: $jkey => $jval\n";
if( $ikey eq $mkey ) {
$hash3{ $ikey } = $ival . " " . $jval;
$found = 1;
}
}
if( $found == 1 ) {
$nothash{ $ikey } = $ival;
$found = 0;
}
}
print "Hash3: ", %hash3, "\n";
print "Not found: ", %nothash, "\n";
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/