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

Dear Monks,
I've two hash tables: %files_by_channel and %files_by_number.

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $channel_name; my %files_by_channel = ( 'ch1' => { '00014' => '/foo/oradata/bar/foodb-lob01.dbf', '00008' => '/foo/oradata/bar/foodb-index11.dbf', }, 'ch2' => { '00004' => '/foo/oradata/bar/tools01.dbf', '00019' => '/foo/oradata/bar/foodb-data02.dbf', '00003' => '/foo/oradata/bar/undotbs01.dbf' }, ); my %files_by_number = ( '00008' => '/foo/oradata/bar/foodb-index11.dbf', '00004' => '/foo/oradata/bar/tools01.dbf', '00003' => '/foo/oradata/bar/undotbs01.dbf', '00019' => '/foo/oradata/bar/foodb-data02.dbf', '00014' => '/foo/oradata/bar/foodb-lob01.dbf' ); #print Dumper \%files_by_channel; #print Dumper \%files_by_number; print "\n"; printf "%-10s %-15s %-40s\n", 'File#', 'Channel Name', 'File Name'; printf "%-10s %-15s %-40s\n", '-' x 10, '-' x 15, '-' x 40; foreach my $file_number (sort keys %files_by_number) { foreach $channel_name ( %files_by_channel ) { #TO DO } printf "%-10s %-15s %-40s\n", $file_number, $channel_name, $files_ +by_number{$file_number}; }

How to integrate (conjoin) information from these two corresponding tables that the result is something like the following?

File# Channel Name File Name ---------- --------------- ---------------------------------------- 00003 ch2 /foo/oradata/bar/undotbs01.dbf 00004 ch2 /foo/oradata/bar/tools01.dbf 00008 ch1 /foo/oradata/bar/foodb-index11.dbf 00014 ch1 /foo/oradata/bar/foodb-lob01.dbf 00019 ch2 /foo/oradata/bar/foodb-data02.dbf

Thank you very much in advance for your help.

Best regards,
--
Scottie

Replies are listed 'Best First'.
Re: How-To integrate information from two hash tables?
by davido (Cardinal) on Jun 13, 2011 at 22:36 UTC

    It doesn't seem like you need the second hash at all. You just need the first one arranged differently.

    use strict; use warnings; use Data::Dumper; my $channel_name; my %files_by_channel = ( 'ch1' => { '00014' => '/foo/oradata/bar/foodb-lob01.dbf', '00008' => '/foo/oradata/bar/foodb-index11.dbf', }, 'ch2' => { '00004' => '/foo/oradata/bar/tools01.dbf', '00019' => '/foo/oradata/bar/foodb-data02.dbf', '00003' => '/foo/oradata/bar/undotbs01.dbf' }, ); my %rearranged; foreach my $ch ( keys %files_by_channel ) { my $file_ref = $files_by_channel{$ch}; foreach my $file ( keys %{$file_ref} ) { $rearranged{$file} = [ $ch, $file_ref->{$file} ] } } printf "%-10s %-15s %-40s\n", 'File#', 'Channel Name', 'File Name'; printf "%-10s %-15s %-40s\n", '-' x 10, '-' x 15, '-' x 40; printf "%-10s %-15s %-40s\n", $_, @{ $rearranged{$_} } for sort keys %rearranged;

    Dave

      On Jun 13, 2011 at 22:36 UTC, Dave (davido) wrote:
      > It doesn't seem like you need the second hash at all.
      > You just need the first one arranged differently.
      Unfortunately I can't use only a single array. I gave only a simplified example (code) in my question. In fact, I parse the two outputs:
      (1) Output log file from Oracle RMAN session, where I've informations about the channels. For example:

      allocated channel: ch1 channel ch1: SID=208 device type=DISK allocated channel: ch2 channel ch2: SID=403 device type=DISK channel ch1: specifying datafile(s) in backup set input datafile file number=00014 name=/foo/oradata/bar/foodb-lob01.dbf input datafile file number=00008 name=/foo/oradata/bar/foodb-index11.d +bf (...) channel ch2: specifying datafile(s) in backup set input datafile file number=00004 name=/foo/oradata/bar/tools01.dbf input datafile file number=00019 name=/foo/oradata/bar/foodb-data02.db +f input datafile file number=00003 name=/foo/oradata/bar/undotbs01.dbf

      (2) The output from `RMAN> list backup` command, where I've a lot of informations about the backups. For example:

      BS Key Type LV Size Device Type Elapsed Time Completion Time ------- ---- -- ---------- ----------- ------------ --------------- 100 Full 509.78M DISK 00:01:03 15-FEB-07 BP Key: 202 Status: AVAILABLE Compressed: YES Tag: DB_FULL +_DAILY_20110613_142608 Piece Name: /VNB_foo_rman/NEW_FOODB_RMAN/2011_06_13/FOODB_DB_F +ULL_DAILY_1_53_1lmepls6_20110613.dbf List of Datafiles in backup set 200 File LV Type Ckp SCN Ckp Time Name ---- -- ---- ---------- --------- ---- 14 Full 421946 15-FEB-07 /foo/oradata/bar/foodb-lob01.dbf 19 Full 421946 15-FEB-07 /foo/oradata/bar/foodb-data02.dbf BS Key Type LV Size Device Type Elapsed Time Completion Time ------- ---- -- ---------- ----------- ------------ --------------- 101 Full 509.78M DISK 00:01:03 15-FEB-07 BP Key: 202 Status: AVAILABLE Compressed: YES Tag: DB_FULL +_DAILY_20110613_142608 Piece Name: /VNB_foo_rman/NEW_FOODB_RMAN/2011_06_13/FOODB_DB_F +ULL_DAILY_1_54_1mmepls6_20110613.dbf List of Datafiles in backup set 200 File LV Type Ckp SCN Ckp Time Name ---- -- ---- ---------- --------- ---- 4 Full 421946 15-FEB-07 /foo/oradata/bar/tools01.dbf 8 Full 421946 15-FEB-07 /foo/oradata/bar/foodb-index11.dbf 3 Full 421946 15-FEB-07 /foo/oradata/bar/undotbs01.dbf

      So, first (1) goes to the "%files_by_channel" array, and second (2) goes to the "%files_by_number" array. But like I said before, this is just a simplified example, because the "%files_by_number" array contains much more information than I showed. It was interesting only for me how to combine information from these two hash arrays.

      Scottie

Re: How-To integrate information from two hash tables?
by Your Mother (Archbishop) on Jun 13, 2011 at 22:44 UTC

    davido's answer is good if you can get your data straight from the top. If not, this makes a little map for you and gives the output you're looking for.

    my %channel_map; for my $channel ( keys %files_by_channel ) { $channel_map{$_} = $channel for keys %{ $files_by_channel{$channel +} }; } printf "%-10s %-15s %-40s\n", 'File#', 'Channel Name', 'File Name'; printf "%-10s %-15s %-40s\n", '-' x 10, '-' x 15, '-' x 40; for my $file_number ( sort keys %files_by_number ) { printf "%-10s %-15s %-40s\n", $file_number, $channel_map{$file_number}, $files_by_number{$file_number}; }

      "Your Mother",
      Your solution works perfectly! :) Thank you so much.

      Best regards,
      --
      Scottie