Perl: Sorting a hash value that is a list.


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl: Sorting a hash value that is a list.
# 1  
Old 02-29-2012
Perl: Sorting a hash value that is a list.

Hi Folks
I am very much a newbie at perl but picking it up and I'm hoping you can help.

I have a file input that details all the /etc/group files in our enterprise in the following format: "<host>:<group>:<gid>:<users>"

I want to parse this data display it as the following: "<group>:<gid>:<users>"

So i can trace which users are members of each group (regardless of the host).

So far I have used a hash and am using <group>:<gid> as my key.

This is my code so far:
Code:
#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
my $cwd = cwd;
my $file = $cwd . '/usrgrps.txt';
my $gid;
my $grp;
my $host;
my $group;
my $userid;
my %table = ();
open(FILE, "<", $file) or die "Can't open $file:$!";
while(<FILE>) {
chomp;
($host, $grp, $gid, $userid) = split(/
+:/, $_);
$group = "$grp:$gid";
push @{$table{$group}}, $userid;
}
foreach $group (sort keys %table) {
print "$group:";
my @users = @{$table{$group}};
print join ',', sort @users;
print "\n";
}
 
my $number = values %table; 
print $number . "\n";

This is roughly my input file:
Code:
host1:group1:9001:user1,user2,user3,user4,user5
host1:group2:9002:user1,user2,user3
host1:group3:9003:user1,user2,user4
host1:group4:9004:user1,user2,user5
host1:group5:9005:user1,user2
host1:group6:9006:
host2:group1:9001:user1,user2,user3,user4,user5
host2:group2:9002:user1,user2,user3
host2:group3:9003:user1,user2,user4
host2:group4:9004:user1,user2,user5
host2:group5:9005:user1,user2
host2:group1:9006:
host3:group1:9001:user1,user2,user3,user4,user5
host3:group2:9002:user1,user2,user3
host3:group3:9003:user1,user2,user4
host3:group4:9004:user1,user2,user5
host3:group5:9005:user1,user2
host3:group1:9006:

This is what I am getting back:
Code:
group1:9001:user1,user2,user3,user4,user5,user1,user2,user3,user4,user5,user1,user2,user3,user4,user5
group2:9002:user1,user2,user3,user1,user2,user3,user1,user2,user3
group3:9003:user1,user2,user4,user1,user2,user4,user1,user2,user4
group4:9004:user1,user2,user5,user1,user2,user5,user1,user2,user5
group5:9005:user1,user2,user1,user2,user1,user2
group6:9006:,,,

My question is, how do I get only unique elements assigned to each key? Any help or advise you can offer will be greatly appreciated. Thanks in advance

Last edited by Franklin52; 02-29-2012 at 07:25 AM.. Reason: Please use code tags for code and data samples, thank you
# 2  
Old 02-29-2012
perl

can you post your expected output ?
you need to get the unique users for each group ?
# 3  
Old 02-29-2012
Yes, my expected output is a list of unique userid per each group.
# 4  
Old 02-29-2012
Please post a sample of your desired output. Something like.. this is how my output should look!
This User Gave Thanks to balajesuri For This Post:
# 5  
Old 02-29-2012
Thanks for quick replies:

This is how my output should look:

group1:9001:user1,user2,user3,user4,user5
group1:9006:
group2:9002:user1,user2,user3
group3:9003:user1,user2,user4
group4:9004:user1,user2,user5
group5:9005:user1,user2
group6:9006:
# 6  
Old 02-29-2012
Code:
#!/usr/bin/perl
use strict;
use warnings;

my ($gid, $grp, $host, $group, $userid);
my %table;

open FILE, "< /path/to/usrgrps.txt";
foreach (<FILE>) {
    chomp;
    ($host, $grp, $gid, $userid) = split /:/;
    $group = "$grp:$gid";
    if (length ($userid) != 0) {
        (defined $table{$group} && $table{$group} =~ /$_/) ? next : ($table{$group}.="$_,") foreach (split /,/, $userid);
    }
    else {
        $table{$group} = "";
    }
}
close FILE;

foreach (sort keys %table) {
    $table{$_} =~ s/,$//;
    print "$_:$table{$_}\n";
}


Last edited by balajesuri; 02-29-2012 at 06:06 AM..
This User Gave Thanks to balajesuri For This Post:
# 7  
Old 02-29-2012
perl

Hi,

Try this one,

Code:
#!/usr/bin/perl
use strict;
use Cwd;
my $cwd = cwd;
my $file = $cwd . '/usrgrps.txt';
my $gid;
my $grp;
my $host;
my $group;
my $userid;
my %table = ();
open(FILE, "<", $file) or die "Can't open $file:$!";
while(<FILE>)
{
chomp;
($host, $grp, $gid, $userid) = split(/\:/, $_);
$group = "$grp:$gid";
my @users=split(/\,/,$userid);
if ( scalar(@users) )
{
   foreach my $user ( @users )
   {
      push(@{$table{$group}}, $user) if ( ! grep{/$user/} @{$table{$group}} );
   }
}
else
{
   push @{$table{$group}}, $userid;
}
}
foreach $group (sort keys %table) {
print "$group:";
my @users = @{$table{$group}};
print join ',', sort @users;
print "\n";
}

Cheers,
RangaSmilie
This User Gave Thanks to rangarasan For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

Perl: restrict perl from automaticaly creating a hash branches on check

My issue is that the perl script (as I have done it so far) created empty branches when I try to check some branches on existence. I am using multydimentional hashes: found it as the best way for information that I need to handle. Saing multidimentional I means hash of hashes ... So, I have ... (2 Replies)
Discussion started by: alex_5161
2 Replies

2. Shell Programming and Scripting

Compare values of hashes of hash for n number of hash in perl without sorting.

Hi, I have an hashes of hash, where hash is dynamic, it can be n number of hash. i need to compare data_count values of all . my %result ( $abc => { 'data_count' => '10', 'ID' => 'ABC122', } $def => { 'data_count' => '20', 'ID' => 'defASe', ... (1 Reply)
Discussion started by: asak
1 Replies

3. Shell Programming and Scripting

Sorting values of hash in ascending order using Perl

I want to sort values of a hash in ascending order. my %records; for my $value (sort values %records){print $value,"\n";} When I use the above code I get values in this order: 1,10,11,2,3,4,5,6,7,8,9. But, I need values in my output in this order: 1,2,3,4,5,6,7,8,9,10,11. Can Someone... (1 Reply)
Discussion started by: koneru_18
1 Replies

4. Shell Programming and Scripting

Perl hash help

Hi , i have the below code its working fine when i execute in unix , but its not working in windows could you pls explain me where i am going wrong. This is the program $data = { '1' => 'one' , '2' => 'two' , 3 => 'three' }; print "hello : $data->{'1'}... (2 Replies)
Discussion started by: ragilla
2 Replies

5. Shell Programming and Scripting

Sorting the alpha numeric results of Hash

Hi All I've got a perl script that I'm having a problem with when it prints the output of a hash. Some background. I'm trying to merge two file with a similar structure but with different data. Here is a portion of the script I'm using. while (<INPUT>) { my... (0 Replies)
Discussion started by: kingpin2502
0 Replies

6. Shell Programming and Scripting

Remove default data hash sorting in perl script?

Hi, I have a datahash with 'n' number of values in perl script. I am writing a xml file from the datahash. I am getting output with sorting(Field sorting). My question is that i don't want any default sorting.whatever i am inserting into datahash it should give same xml file. Any help? ... (0 Replies)
Discussion started by: solo123
0 Replies

7. Shell Programming and Scripting

Sorting keys of a hash in perl

hi all, i have a small problem regarding sorting the keys in a hash. my %hash; for($i=0;$i<19;$i++) { $hash{$i}=$i; } foreach $c (sort keys %hash) { print "\n $hash{$c}"; } (1 Reply)
Discussion started by: niteesh_!7
1 Replies

8. Shell Programming and Scripting

perl hash - using a range as a hash key.

Hi, In Perl, is it possible to use a range of numbers with '..' as a key in a hash? Something in like: %hash = ( '768..1536' => '1G', '1537..2560' => '2G' ); That is, the range operation is evaluated, and all members of the range are... (3 Replies)
Discussion started by: dsw
3 Replies

9. Shell Programming and Scripting

Perl Hash:Can not keep hash data in the same order that it was inserted

Can Someone explain me why even using Tie::IxHash I can not get the output data in the same order that it was inserted? See code below. #!/usr/bin/perl use warnings; use Tie::IxHash; use strict; tie (my %programs, "Tie::IxHash"); while (my $line = <DATA>) { chomp $line; my(... (1 Reply)
Discussion started by: jgfcoimbra
1 Replies

10. Shell Programming and Scripting

Print Entire hash list (hash of hashes)

I have a script with dynamic hash of hashes , and I want to print the entire hash (with all other hashes). Itried to do it recursively by checking if the current key is a hash and if yes call the current function again with refference to the sub hash. Most of the printing seems to be OK but in... (1 Reply)
Discussion started by: Alalush
1 Replies
Login or Register to Ask a Question