Home > Archive > PERL Beginners > September 2007 > Pbm in Sorting the hash
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Pbm in Sorting the hash
|
|
| Sivasakthi 2007-09-21, 7:00 pm |
| Hi all,
I have file like that following,
site_name access_time
www.google.com 14:13:04|14:13:04|
172.16.5.49 14:12:10|14:12:56|
172.16.65.53 14:12:41|14:12:58|
172.16.671.35 14:12:29|
from the above file i need to print the sites & no of accessed
connections with sort.
open(FILE,:/tmp/test.txt/" or die "cant open the file");
my @domain_info=<FILE>;
foreach my $site (@domain_info)
{
my ($domain,$data)=split(" ",$site);
$domain{$domain}.=$data;
}
foreach my $dname ( keys %domain)
{
my @conn=split('\|',$domain{$dname});
my $noofconn=$#conn+1;
$noofconns{$dname}+=$noofconn;
}
foreach $dname (sort {$noofconns{$b} <=> $noofconns{$a}} %noofconns)
{
print "$domain\n";
print "$noofconns\n";
}
close (<FILE> );
Could u help me to solve the pbm???
Thanks,
Siva
| |
| Tom Phoenix 2007-09-21, 7:00 pm |
| On 9/21/07, sivasakthi <msivasakthi@gmail.com> wrote:
> open(FILE,:/tmp/test.txt/" or die "cant open the file");
You probably meant a quote mark instead of a colon there.
> foreach $dname (sort {$noofconns{$b} <=> $noofconns{$a}} %noofconns)
It looks as if you want to use the keys() function there, just before
the name of the hash.
Hope this helps!
--Tom Phoenix
Stonehenge Perl Training
| |
| Rob Dixon 2007-09-21, 7:00 pm |
| sivasakthi wrote:
> Hi all,
>
> I have file like that following,
>
> site_name access_time
> www.google.com 14:13:04|14:13:04|
> 172.16.5.49 14:12:10|14:12:56|
> 172.16.65.53 14:12:41|14:12:58|
> 172.16.671.35 14:12:29|
>
> from the above file i need to print the sites & no of accessed
> connections with sort.
>
>
> open(FILE,:/tmp/test.txt/" or die "cant open the file");
>
> my @domain_info=<FILE>;
> foreach my $site (@domain_info)
> {
> my ($domain,$data)=split(" ",$site);
> $domain{$domain}.=$data;
> }
>
> foreach my $dname ( keys %domain)
> {
> my @conn=split('\|',$domain{$dname});
> my $noofconn=$#conn+1;
> $noofconns{$dname}+=$noofconn;
>
> }
> foreach $dname (sort {$noofconns{$b} <=> $noofconns{$a}} %noofconns)
> {
> print "$domain\n";
> print "$noofconns\n";
> }
> close (<FILE> );
>
> Could u help me to solve the pbm???
use strict;
use warnings;
my %noofconns;
open FILE, '/tmp/test.txt' or die "Can't open the file";
while (<FILE> ) {
my ($domain, $data) = split;
my $count = $data =~ tr/|//;
next unless $count;
$noofconns{$domain} += $count;
}
close FILE;
foreach my $domain (sort {$noofconns{$b} <=> $noofconns{$a}} keys %noofconns) {
print "$domain\n";
print "$noofconns{$domain}\n";
}
Rob
| |
| Chas. Owens 2007-09-21, 7:00 pm |
| On 9/21/07, sivasakthi <msivasakthi@gmail.com> wrote:
> Hi all,
>
> I have file like that following,
>
> site_name access_time
> www.google.com 14:13:04|14:13:04|
> 172.16.5.49 14:12:10|14:12:56|
> 172.16.65.53 14:12:41|14:12:58|
> 172.16.671.35 14:12:29|
>
> from the above file i need to print the sites & no of accessed
> connections with sort.
>
To start with, all Perl programs longer than one line should start with
#!/usr/bin/perl
use strict;
use warnings;
>
> open(FILE,:/tmp/test.txt/" or die "cant open the file");
Your use of parenthesis is defeating your use of "or die". This code
will only die if "/tmp/test.txt" is false (which it cannot be as it is
a non-empty string). You also have what I hope is a type there at the
start of the file string (: instead of "). Don't type code into
emails, always copy and paste. Try doing it like this instead
open my $file, '<', '/tmp/test.txt'
or die "could not open /tmp/test.txt: $!\n";
>
> my @domain_info=<FILE>;
> foreach my $site (@domain_info)
This is the worst way to read a file line by line. You are wasting
CPU time and memory. The right way is
while (my $site = <$file> ) {
> {
> my ($domain,$data)=split(" ",$site);
> $domain{$domain}.=$data;
The data structure you want here is not a hash of strings, but a hash
of arrays. Try
push @{$domain{$domain}}, $data;
or better yet
push @{$domain{$domain}}, split '|', $data;
> }
>
> foreach my $dname ( keys %domain)
> {
> my @conn=split('\|',$domain{$dname});
> my $noofconn=$#conn+1;
> $noofconns{$dname}+=$noofconn;
>
> }
This loop should be joined with the one above (see the second example)
> foreach $dname (sort {$noofconns{$b} <=> $noofconns{$a}} %noofconns)
sort takes a list not a hash, you need to say "sort {} keys %hash" instead.
> {
> print "$domain\n";
> print "$noofconns\n";
I think this is where your real problem is. $domain and $noofconns
hold nothing (they aren't even variables under strict). You should
have said
print "$dname had $noofconns{$dname} connections\n";
> }
> close (<FILE> );
>
> Could u help me to solve the pbm???
>
> Thanks,
> Siva
>
>
Here is how I would have solved the same requirements (if the sort is
too slow then it might be time to try a Schwartzian Transform on it):
#!/usr/bin/perl
use strict;
use warnings;
my %domain;
while (<DATA> ) {
my ($dom, $data) = split ' ';
push @{$domain{$dom}}, split /\|/, $data;
}
for my $dom (sort { @{$domain{$b}} <=> @{$domain{$a}} } keys %domain) {
print "$dom had " . @{$domain{$dom}} . " connections\n";
}
__DATA__
site_name access_time
www.google.com 14:13:04|14:13:04|
172.16.5.49 14:12:10|14:12:56|
172.16.65.53 14:12:41|14:12:58|
172.16.671.35 14:12:29|
| |
| John W. Krahn 2007-09-21, 9:59 pm |
| sivasakthi wrote:
> Hi all,
Hello,
> I have file like that following,
>
> site_name access_time
> www.google.com 14:13:04|14:13:04|
> 172.16.5.49 14:12:10|14:12:56|
> 172.16.65.53 14:12:41|14:12:58|
> 172.16.671.35 14:12:29|
>
> from the above file i need to print the sites & no of accessed
> connections with sort.
>
>
> open(FILE,:/tmp/test.txt/" or die "cant open the file");
You have a typo, :/tmp/test.txt/" should be "/tmp/test.txt". Also, you should
include the $! variable in the error message so you know *why* it failed.
open FILE, '<', '/tmp/test.txt' or die "cant open the file: $!";
> my @domain_info=<FILE>;
> foreach my $site (@domain_info)
> {
> my ($domain,$data)=split(" ",$site);
> $domain{$domain}.=$data;
> }
>
> foreach my $dname ( keys %domain)
> {
> my @conn=split('\|',$domain{$dname});
> my $noofconn=$#conn+1;
> $noofconns{$dname}+=$noofconn;
>
> }
There is really no good reason to read in the entire file at once:
my %noofconns;
while ( <FILE> ) {
my ( $domain, $data ) = split;
my @conn = split /\|/, $data;
$noofconns{ $domain } += @conn;
}
close FILE;
> foreach $dname (sort {$noofconns{$b} <=> $noofconns{$a}} %noofconns)
You forgot to use keys():
foreach my $dname ( sort {$noofconns{$b} <=> $noofconns{$a}} keys %noofconns )
> {
> print "$domain\n";
> print "$noofconns\n";
print "$dname $noofconns{$dname}\n";
> }
> close (<FILE> );
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
| |
| Dr.Ruud 2007-09-22, 7:00 pm |
| sivasakthi schreef:
> Could u help me to solve the pbm???
Try this first:
s/\bu\b/you/
s/\bpbm\b/problem/
s/\?{3}/?/
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| Sivasakthi 2007-09-24, 4:00 am |
| On Fri, 2007-09-21 at 12:47 -0400, Chas. Owens wrote:
> On 9/21/07, sivasakthi <msivasakthi@gmail.com> wrote:
>
Thank you all for your response..
Thanks,
Siva
|
|
|
|
|