how to perform merging of keys for common values in hash of hash in perl - perl

I am working on a below hash of hashes in perl, wherein i have some values in
inner hash that are same for different key timestamps. Is there any way to merge the timestamp keys for similar values?
'Test Responder Data String' => {
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20' => 'xxy00171329968;data1',
'2018-01-27' => 'xxy00171329968;data1',
'2018-01-28' => 'xxy00171329968;data1'
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05' => 'aaa00175033226;response try',
'2018-01-08' => 'aaa00175033226;response try'
}
Expected Result:
'Test Responder Data String' => {
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20,2018-01-27,2018-01-28' => 'xxy00171329968;data1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05,2018-01-08' => 'aaa00175033226;response try'
}

my %h=(
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20' => 'xxy00171329968;data1',
'2018-01-27' => 'xxy00171329968;data1',
'2018-01-28' => 'xxy00171329968;data1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05' => 'aaa00175033226;response try',
'2018-01-08' => 'aaa00175033226;response try'
);
my %t;
push #{ $t{ $h{$_} } }, $_ for keys %h;
my %result = map { join(",", #{$t{$_}}) => $_ } keys %t;
use Data::Dumper; print Dumper \%result;
output
$VAR1 = {
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05,2018-01-08' => 'aaa00175033226;response try',
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-27,2018-01-20,2018-01-28' => 'xxy00171329968;data1'
};

Related

Split values from hash to another hash in perl

I have a Hash like this. In this there are some repeated values like ID and VALUES are coming as shown in the given below code.
HASH = {
TEST => 'xxx',
STACK => 1,
'ID{0}' => '111',
'ID{1}' => '222',
'VALUE{0}' => 'Test',
'VALUE{1}' => 'Sample',
};
I want to take these values out to another Hash as given below.
Hash ={
0 => { ID => '111', VALUE => 'Test }
1 => { ID => '222', VALUE => 'Sample' }
}
How i can do this in Perl?
you need to make a hash of hashes
%hash =
(
TEST => 'xxx',
STACK => 1,
1 => {
'ID' => '111',
'VALUE' => 'Test',
} ,
2 => {
'ID' => '222',
'VALUE' => 'Sample',
}
);
to access them
$hash{1}->{ID};
here is a link for more info on hash of hashes LINK

Hashes of Arrays of Hashes of Arrays

I have the following output from hash in perl:
$VAR1 = {
'ins_api' => {
'sid' => 'eoc',
'outputs' => {
'output' => [
{
'body' => {
'TABLE_interface' => {
'ROW_interface' => [
{
'vdc_lvl_in_pkts' => 17081772,
'vdc_lvl_in_avg_bits' => 3128,
'eth_autoneg' => 'on',
'eth_speed' => '1000 Mb/s',
'admin_state' => 'up',
'vdc_lvl_out_mcast' => '65247',
'state' => 'up',
'eth_mtu' => '1500',
'eth_hw_addr' => '78ba.f9ad.b248',
'eth_mdix' => 'off',
'interface' => 'mgmt0',
'eth_ip_addr' => '10.56.32.84',
'eth_bw' => 1000000,
'vdc_lvl_in_avg_pkts' => '3',
'vdc_lvl_out_bytes' => '3463952330',
'vdc_lvl_in_ucast' => '7653891',
'eth_ip_prefix' => '10.',
'eth_rxload' => '1',
'eth_txload' => '1',
'eth_reliability' => '255',
'eth_dly' => 10,
'vdc_lvl_in_mcast' => '8742911',
'eth_ip_mask' => 24,
'eth_bia_addr' => '78ba.f9ad.b248',
'eth_duplex' => 'full',
'vdc_lvl_out_pkts' => '8668507',
'vdc_lvl_out_avg_pkts' => '1',
'vdc_lvl_in_bcast' => '684970',
'vdc_lvl_out_avg_bits' => '1840',
'medium' => 'broadcast',
'vdc_lvl_out_bcast' => '5',
'vdc_lvl_out_ucast' => '8603255',
'eth_ethertype' => '0x0000',
'vdc_lvl_in_bytes' => '1985125644',
'eth_hw_desc' => 'GigabitEthernet'
},
{
'eth_babbles' => '0',
'eth_outbytes' => '7362149107971',
'eth_outucast' => '16348249961',
'eth_clear_counters' => 'never',
'eth_watchdog' => '0',
'eth_inpkts' => 8644872191,
'eth_inbytes' => '3415386845315',
'eth_out_flowctrl' => 'off',
'eth_bad_proto' => '0',
'eth_frame' => '0',
----- output omitted -------
},
What would be the best way to loop via ROW_interface array and print some of the elements? I am just trying to get the elements in the ROW_interface array.
my $ROW_Interfaces = $output->{body}{TABLE_interface}{ROW_interface};
for my $ROW_Interfaces (#$ROW_Interfaces) {
...
}
It seems there can be more than one output, so you'll have to locate the appropriate one similarly.
Similar to #ikegami's answer, but handles the multiple output entries. The if defined... is there as the structure isn't complete, and I wasn't sure if each entry had the same keys or not.
for my $output (#{ $VAR1->{ins_api}{outputs}{output} }){
for my $row_int (#{ $output->{body}{TABLE_interface}{ROW_interface} }){
print "$row_int->{eth_frame}\n" if exists $row_int->{eth_frame};
}
}

Converting a multi dimensional hash to a csv

I have a multidimensional hash, that i am printing on the screen, i want to convert the hash to a CSV formatted data.
Sample output of my script
$VAR1 = {
'1' => {
'EVENT_NAME' => '"x1"',
'NV_MANAGED_OBJECT_INSTANCE' => '"SubNetwork=ONRM_RootMo,SubNetwork=AXE,ManagedElement=WBSC1,BssFunction=BSS_ManagedFunction,BtsSiteMgr=WV5619"',
'EVENT_TYPE' => '"x5"',
'NV_MANAGED_OBJECT_CLASS' => '"BtsSiteMgr"',
'AdditionalText_Line03' => '"MO RSITE ALARM SLOGAN"',
'NV_SPECIFIC_PROBLEM' => '"RADIO X-CEIVER ADMINISTRATION MANAGED OBJECT FAULT"',
'ResynchEvent' => '"false"',
'SubNetwork' => '"ONRM_RootMo"',
'SubNetwork_0' => '"ONRM_RootMo"',
'NV_PROBABLE_CAUSE' => '"0"',
'AdditionalText_Line04' => '"RXOCF-87 WV5619 BTS EXTERNAL"',
'RawCaptureTimeStamp' => '1449806147',
'BssFunction' => '"BSS_ManagedFunction"',
'DOMAIN_NAME' => '"ALARM_IRP_VERSION_1_1"',
'AdditionalText_Line02' => '"MANAGED OBJECT FAULT"',
'NV_PROPOSED_REPAIR_ACTIONS' => '""',
'NV_ACK_TIME' => '"12/11/15 4:55:45 AM"',
'AdditionalText_Line01' => '"RADIO X-CEIVER ADMINISTRATION"',
'NV_ACK_STATE' => '"2"',
'NV_SYSTEM_DN' => '"Ericsson OSS IRPAgent"',
'ManagedElement' => '"WBSC1"',
'SubNetwork_1' => '"AXE"',
'BtsSiteMgr' => '"WV5619"',
'NV_EVENT_TIME' => '"12/11/15 4:55:00 AM"',
'AdditionalText_Line06' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'AdditionalText_LineCount' => '"7"',
'AdditionalText_Line05' => '"END"',
'AdditionalText_Line00' => '"*** ALARM 505 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0455"',
'NV_ADDITIONAL_TEXT' => '"*** ALARM 505 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0455\\nRADIO X-CEIVER ADMINISTRATION\\nMANAGED OBJECT FAULT\\n\\nMO RSITE ALARM SLOGAN\\nRXOCF-87 WV5619 BTS EXTERNAL\\n\\nEND\\n-ProbableCause(OSS)=Different causes possible for same message"',
'NV_NOTIFICATION_ID' => '"2267705"',
'AdditionalText_Line07' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'NV_ACK_USER_ID' => '""',
'NV_ALARM_ID' => '"55079020"',
'NV_PERCEIVED_SEVERITY' => '"4"'
},
'0' => {
'EVENT_NAME' => '"x4"',
'NV_MANAGED_OBJECT_INSTANCE' => '"SubNetwork=ONRM_RootMo,SubNetwork=AXE,ManagedElement=WBSC1,BssFunction=BSS_ManagedFunction,BtsSiteMgr=WV5619"',
'EVENT_TYPE' => '"x5"',
'NV_MANAGED_OBJECT_CLASS' => '"BtsSiteMgr"',
'AdditionalText_Line03' => '"MO RSITE ALARM SLOGAN"',
'NV_SPECIFIC_PROBLEM' => '"RADIO X-CEIVER ADMINISTRATION MANAGED OBJECT FAULT"',
'ResynchEvent' => '"false"',
'SubNetwork' => '"ONRM_RootMo"',
'SubNetwork_0' => '"ONRM_RootMo"',
'NV_PROBABLE_CAUSE' => '"0"',
'AdditionalText_Line04' => '"RXOCF-87 WV5619 BTS EXTERNAL"',
'RawCaptureTimeStamp' => '1449806146',
'BssFunction' => '"BSS_ManagedFunction"',
'DOMAIN_NAME' => '"ALARM_IRP_VERSION_1_1"',
'AdditionalText_Line02' => '"MANAGED OBJECT FAULT"',
'NV_PROPOSED_REPAIR_ACTIONS' => '""',
'NV_ACK_TIME' => '"12/11/15 4:55:45 AM"',
'AdditionalText_Line01' => '"RADIO X-CEIVER ADMINISTRATION"',
'NV_ACK_STATE' => '"2"',
'NV_SYSTEM_DN' => '"IRPAgent"',
'ManagedElement' => '"WBSC1"',
'SubNetwork_1' => '"AXE"',
' Status_TicketType' => '0',
'BtsSiteMgr' => '"WV5619"',
'NV_EVENT_TIME' => '"12/11/15 4:55:00 AM"',
'AdditionalText_Line06' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'AdditionalText_LineCount' => '"7"',
'AdditionalText_Line05' => '"END"',
'AdditionalText_Line00' => '"*** ALARM 504 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0451"',
'NV_ADDITIONAL_TEXT' => '"*** ALARM 504 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0451\\nRADIO X-CEIVER ADMINISTRATION\\nMANAGED OBJECT FAULT\\n\\nMO RSITE ALARM SLOGAN\\nRXOCF-87 WV5619 BTS EXTERNAL\\n\\nEND\\n-ProbableCause(OSS)=Different causes possible for same message"',
'NV_NOTIFICATION_ID' => '"2267704"',
'NV_ACK_USER_ID' => '""',
'NV_ALARM_ID' => '"55079016"',
'NV_PERCEIVED_SEVERITY' => '"6"'
}
};
Code responsible for traversing the file into a hash:
my $i=0;
open my $cap1, $file or die "Could not open $file: $!";
while( my $line = <$cap1>) {
my #pairs;
my $name;
my $value;
if($line ne ''){
#pairs = split / = /, $line;
$name = $pairs[0];
chomp($name);
$value = $pairs[1];
chomp($value);
}
if($name ne '' && $name !~ /^Status_/){
$data{$i}{$name} = $value;
}
if($name =~ /^RawCaptureTimeStamp/){
$i++;
}
}
print Dumper \%data;
Heads up: The columns in each set of the hash is not fixed. it is dynamic.
However, i have got all possible column names in another array. So you can assume i have all columns (EVENT_NAME,EVENT_TYPE,...) in an array file. Using that i need to convert the existing hash into a CSV.
Found the solution myself:
foreach my $j (sort keys %data) {
foreach (#uniqueNames) {
if(exists($data{$j}{$_})){
print "$data{$j}{$_},";
}
else{
print "\"\"",;
}
}
print "\n";
}
Where #uniqueNames is an array having all possible unique columns from the original hash table.

How to access array of hashes?

Hi i have an array of hashes as below, i want access hash element/elements. Say suppose i want to print doct1's name, i am not getting right result please help me how do i print that?
#doctors = (
'doct1' => {
'name' => 'abcd',
'specialization' => 'xyz',
'city' => 'pqr'
},
'doct2' => {
'name' => 'efgh',
'specialization' => 'mno',
'city' => 'stu'
}
);
print $doctors[0]{'name'};
Arrays don't have keys,
my #doctors = (
{
'name' => 'abcd',
'specialization' => 'xyz',
'city' => 'pqr'
},
{
'name' => 'efgh',
'specialization' => 'mno',
'city' => 'stu'
}
);
print $doctors[0]{'name'};
You don't have an AoH. You have an array containing both strings and references to hashes. This is a very poor data structure. It's messy and inefficient to locate the correct doctor.
my $i = 0;
$i += 2 while $i<#doctors && $doctors[$i] ne 'doct1';
die "Not found" if $i > #doctors;
say $doctors[$i+1]{name};
If you had an AoH as you say, it you look something like this:
my #doctors = (
{
id => 'doct1',
name => 'abcd',
specialization => 'xyz',
city => 'pqr',
},
{
id => 'doct2',
name => 'efgh',
specialization => 'mno',
city => 'stu',
},
);
That would be better.
my ($doctor) = grep { $_->{id} eq 'doct1' } #doctors
or die "Not found";
say $doctor->{name};
It's also possible that doct1 and doct2 are meaningless, and that you'd be happy using 0 and 1 instead. If so,
die "Not found" if #doctors < 0;
say $doctors[0]{name};
If doct1 and doct2 aren't meaningless, then the cleanest and most efficient solution would be to use an HoH.
my %doctors = (
doct1 => {
name => 'abcd',
specialization => 'xyz',
city => 'pqr',
},
doct2 => {
name => 'efgh',
specialization => 'mno',
city => 'stu',
},
);
The code would then be the simple:
my $doctor = $doctors{doct1}
or die "Not found";
say $doctor->{name};
This is a situation where using Data::Dumper is essential, what you actually have is an array of two strings and two hashrefs. If you were to print it out with Data::Dumper you would see this:
use Data::Dumper;
print Dumper \#doctors;
[
'doct1',
{
'city' => 'pqr',
'specialization' => 'xyz',
'name' => 'abcd'
},
'doct2',
{
'city' => 'stu',
'specialization' => 'mno',
'name' => 'efgh'
}
];
Each hashref has all the data that represents a doctor, the additional key at the front doesn't make any sense. Remove those keys and you will have a structure like this:
#doctors = (
{
'name' => 'abcd',
'specialization' => 'xyz',
'city' => 'pqr'
},
{
'name' => 'efgh',
'specialization' => 'mno',
'city' => 'stu'
}
);
and now you can access the hash attributes like you would expect:
print $doctors[0]{name};
The right hand declaration is not very consistent (in intention) with the assignment to an array. You'd probably want to assign it to a hash instead:
%doctors = (
'doct1' => {
'name' => 'abcd',
'specialization' => 'xyz',
'city' => 'pqr'
},
'doct2' => {
'name' => 'efgh',
'specialization' => 'mno',
'city' => 'stu'
}
);
print $doctors{'doct1'}->{'name'};
Either this or, mpapec's answer.

Perl Hash Array foreach issue

I have a response which is displayed through Data::Dumper - Dumper($cat_response->result->{'categories'})
$VAR1 = { 'literature' => '1120', 'law' => '1153', 'arts and crafts' => '1132', 'children' => '1141', 'hobbies' => '1133', 'economy' => '1166', 'jobs' => '1140', 'media' => '1144', 'music' => '1147', 'animals' => '1170', 'business' => '1119', 'diet' => '1122', 'travel reviews' => '1154', 'jewelry' => '1157', 'movies' => '1146', 'television' => '1125', 'politics' => '1168', 'internet' => '1139', 'history' => '1129', 'recipes' => '1156', 'press releases' => '1151', 'presents' => '1128', 'marketing' => '1143', 'translations' => '1162', 'fashion' => '1145', 'technology' => '1163', 'real estate' => '1138', 'computer' => '1173', 'automobile' => '1116', 'finances' => '1126', 'weddings' => '1134', 'games' => '1127', 'esoterism' => '1124', 'horoscopes' => '1135', 'shopping' => '1123', 'humor' => '1137', 'miscellaneous' => '1159', 'science' => '1167', 'programming' => '1152', 'languages' => '1161', 'beauty' => '1117', 'sports' => '1160', 'hotels' => '1136', 'plants' => '1149', 'education' => '1118', 'traveling' => '1155', 'health' => '1130', 'telecommunication' => '1164', 'environment' => '1171', 'software' => '1158', 'sweepstakes' => '1131', 'logistics' => '1142', 'home and family' => '1169', 'news' => '1148' };
To access it, I use:
my %categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%categories)) {
<option value="<% $categories{'$cat'} %>"><% $cat %></option>
}
However, the value of Dumper($cat) is: $VAR1 = 'HASH(0x7fe972641560)';
Did I miss something?
You missing use strict; use warnings; for one. (Well, either that, or you forgot to tell us that Perl told you about your problem.)
$cat_response->result->{'categories'} contains a reference to a hash. Makes no sense to assign that to a hash.
my $categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%$categories)) {
<option value="<% $categories->{'$cat'} %>"><% $cat %></option>
}