Many thanks, everyone, for the useful responses.
I've had a bit of a go with some of the suggestions... and I have something that does what I need (I think - more testing required, as usual). The updated sample code follows:-
# Ref: http://www.perlmonks.com/?node_id=1196078
use Data::Dumper;
%data_hash = ();
%output_hash = ();
@master_dsks = ( 70, 71, 75, 90, 91, 92, 93, 96, 97,
98, 99, 190, 204, 205, 550, 551 );
@master_sites = ( 350, 377, 510, 512, 580, 587,
590, 1100, 1105, 1107, 1108 );
# ----
printf("All Known Dsks:\n"); # Show ALL the known dsks
foreach (@master_dsks) {
printf("%s ", $_);
}
printf("\n\n");
# ----
printf("All Known Sites:\n"); # Show ALL the known sites
foreach (@master_sites) {
printf("%s ", $_);
}
printf("\n\n");
# ----
while( <DATA> ) { # Build list of unique (sit
+e:dsk) items
($site, $buf) = split(/,/, $_);
@input_item = split(/:/, $buf);
foreach $input_field (@input_item) { # EX: "VAR8=36!206!207!"
@dsk_list = ($input_field =~ /([0-9]+)!([0-9]+)!$/); # Get last
+ 2 of 3 items
foreach $dsk (@dsk_list) { # Each dsk item in the inpu
+t...
next if ($dsk == 0); # Skip '0' dsk items
$key = $site . ":" . $dsk; # Build composite key
$data_hash{$key}++; # ...and save it
}
}
}
foreach $key ( sort keys %data_hash ) { # Build list of dsk -> (mul
+ti sites)
($site, $dsk) = split(/:/, $key);
push( @{ $output_hash{$dsk} }, $site ); # ... dsk -> (multi sites)
push( @{ $site_2_dsk{$site} }, $dsk ); # !!! ADDITION !!! ... site
+ -> (multi dsks)
}
# ----
printf("List of sites for each used dsk:\n");
foreach $dsk (sort {$a <=> $b} keys %output_hash) { # Show list of si
+tes for each dsk
printf("Dsk: %d: ... ", $dsk);
foreach $site (sort {$a <=> $b} @{$output_hash{$dsk}}) {
printf(" %d ", $site);
}
printf("\n");
}
printf("\n");
printf("List of dsks for each used site:\n");
foreach $site (sort {$a <=> $b} keys %site_2_dsk) { # Show list of ds
+ks for each site
printf("Site: %d: ... ", $site);
foreach $dsk (sort {$a <=> $b} @{$site_2_dsk{$site}}) {
printf(" %d ", $dsk);
}
printf("\n");
}
printf("\n");
# ----
my %master_dsks_hash = map { $_ , "" } @master_dsks; # Hash of ALL d
+sks
delete @master_dsks_hash{keys %output_hash}; # Delete the US
+ED dsks
@unused_dsks = (keys %master_dsks_hash); # ...leaving th
+e UNUSED dsks
printf("Dsks that are known but unused:\n");
foreach (sort {$a<=>$b} @unused_dsks) {
printf("%s ", $_);
}
printf("\n\n");
# ----
my %master_sites_hash = map { $_ , "" } @master_sites; # Hash of ALL s
+ites
delete @master_sites_hash{keys %site_2_dsk}; # Delete the US
+ED sites
@unused_sites = (keys %master_sites_hash); # ...leaving th
+e UNUSED sites
printf("Sites that are known but unused:\n");
foreach (sort {$a<=>$b} @unused_sites) {
printf("%s ", $_);
}
printf("\n\n");
__DATA__
1108,VAR6=36!204!205!:VAR8=36!206!207!:VAR13=36!70!0!:VAR14=36!70!71!:
+VAR15=36!71!0!
377,VAR12=36!97!96!
512,VAR6=36!90!91!:VAR8=36!92!93!:VAR11=36!0!70!:VAR12=36!189!190!
587,VAR2=36!550!0!:VAR4=36!554!0!:VAR6=36!551!0!
....and the output:-
All Known Dsks:
70 71 75 90 91 92 93 96 97 98 99 190 204 205 550 551
All Known Sites:
350 377 510 512 580 587 590 1100 1105 1107 1108
List of sites for each used dsk:
Dsk: 70: ... 512 1108
Dsk: 71: ... 1108
Dsk: 90: ... 512
Dsk: 91: ... 512
Dsk: 92: ... 512
Dsk: 93: ... 512
Dsk: 96: ... 377
Dsk: 97: ... 377
Dsk: 189: ... 512
Dsk: 190: ... 512
Dsk: 204: ... 1108
Dsk: 205: ... 1108
Dsk: 206: ... 1108
Dsk: 207: ... 1108
Dsk: 550: ... 587
Dsk: 551: ... 587
Dsk: 554: ... 587
List of dsks for each used site:
Site: 377: ... 96 97
Site: 512: ... 70 90 91 92 93 189 190
Site: 587: ... 550 551 554
Site: 1108: ... 70 71 204 205 206 207
Dsks that are known but unused:
75 98 99
Sites that are known but unused:
350 510 580 590 1100 1105 1107
BTW.. Not using the 'warnings' and 'strict' pragmas is fair enough comment.. but this is isolated, sample code... so I'm not too fussed about using them in this context.
Similarly, as I've been cutting code since the 1970s or something, I tend to pre-declare constants, variables, etc at the top of a block or module and then I know where to find all the initializations and comments about the identifiers I use in the code... instead of trying to find the 'first instance' (the 'my' declaration) of an identifier's use in some part of a mass of code when debugging/trying to understand some code - 'tis just easier for me.
..and Re: the issue of 'exists' ... trying to understand the perldoc description gives me too much of a headache:-
A hash or array element can be true only if it's
defined and defined only if it exists, but the reverse
doesn't necessarily hold true.
...but I take the point.
Thanks again for the most useful posts.