text processing - I have two arrays roles added and roles deleted, want to merge them and write in this order in perl -
i have scenario.
file has following fields:
username | roles | type |date | abc|admin |added | 01072015 abc|developer |deleted |01072015 abc|deploy |added |01072015 xyz |admin |deleted |01072015 xyz| deploy|deleted|01072015 cdf|deploy|added|01072015
note here, date going same day, no change now, want printed as
username |roles_added |roles deleted |date abc |admin,deploy |developer |01072015 xyz ||admin,deploy |01072015 cdf |deploy||01072015
i tried below approach given, didn't work out me. please guide me.
#!/usr/bin/perl open(fil,"report.txt") or die("$!"); %k=(); while (my $line=<fil>) { ($user,$roles,$type,$dt)=split(/\|/,$line); $k{$user}{$roles}=1; $k{$user}{$type}=1; } @names=(sort keys(%k)); foreach $name (@names) { foreach $value ( (keys(%{$k{$name}})) ){ print "$value "; } print "$name\n"; } print " here \n"; while( ($k, $v) = each %$k ) { print "key: $k, value: $v.\n"; }
when dealing complex data structures, data::dumper friend. try adding use data::dumper
code , print dumper \%k
after you've finished building %k
hash. you'll see this:
$var1 = { 'xyz' => { ' deploy' => 1, 'deleted' => 1 }, 'username ' => { ' type ' => 1, ' roles ' => 1 }, 'xyz ' => { 'deleted ' => 1, 'admin ' => 1 }, 'cdf' => { 'deploy' => 1, 'added' => 1 }, 'abc' => { 'deleted ' => 1, 'deploy ' => 1, 'developer ' => 1, 'added ' => 1, 'admin ' => 1 } };
see how keys in sub-hashes names after 2 types of things. half of them role names , half of them "added" or "deleted". it's going hard useful out of data structure, let's try different.
where had:
$k{$user}{$roles}=1; $k{$user}{$type}=1;
try instead:
push @{$k{$user}{type}}, $role;
now our data structure looks this:
$var1 = { 'xyz' => { 'deleted' => [ ' deploy' ] }, 'xyz ' => { 'deleted ' => [ 'admin ' ] }, 'cdf' => { 'added' => [ 'deploy' ] }, 'abc' => { 'deleted ' => [ 'developer ' ], 'added ' => [ 'admin ', 'deploy ' ] } };
i think can see it's far easier information want out of data structure. it's basically:
foreach (@names) { print join ',', @{$k{$_}{added}}; print join ',', @{$k{$_}{deleted}}; }
you'll need change code little want.
oh, , please habit of adding use strict
, use warnings
of code. have shown why debugging output @ end of original code wasn't working.
update: threw complete solution.
#!/usr/bin/perl use strict; use warnings; use 5.010; %k; <>; # skip header while (<>) { chomp; ($user, $roles, $type, $dt) = split(/\s*\|\s*/); push @{$k{$user}{$type}}, $roles; $k{$user}{date} = $dt; } 'username |roles_added |roles deleted |date'; foreach $name (sort keys %k) { "$name |", join(',',@{$k{$name}{added} || []}), ' |', join(',',@{$k{$name}{deleted} || []}), ' |', $k{$name}{date}; }
you need pass name of input file command line argument.
Comments
Post a Comment