[11399] in Perl-Users-Digest
Perl-Users Digest, Issue: 4999 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Feb 26 16:20:38 1999
Date: Fri, 26 Feb 99 13:17:06 -0800
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Fri, 26 Feb 1999 Volume: 8 Number: 4999
Today's topics:
Sort question (John )
Re: Sort question (David Cantrell)
Re: Sort question (John )
Re: Sort question (Abigail)
Re: Sort question (Alastair)
Re: Sort question <asquith@macconnect.com>
sorting domain names by levels <mskimin@loraincounty.com>
Re: sorting domain names by levels (Tad McClellan)
sorting info from data files <aaron@tyc.net>
Re: sorting info from data files <jglascoe@giss.nasa.gov>
Re: sorting info from data files (Tad McClellan)
Re: sorting info from data files <jglascoe@giss.nasa.gov>
Re: sorting info from data files <aqumsieh@matrox.com>
Re: sorting info from data files <rick.delaney@home.com>
Re: sorting info from data files droby@copyright.com
Re: sorting info from data files (Larry Rosler)
Sorting long list of IPs. <smiles@wfubmc.edu>
Re: Sorting long list of IPs. <Allan@due.net>
Re: Sorting long list of IPs. <jglascoe@giss.nasa.gov>
Re: Sorting long list of IPs. <kenhirsch@myself.com>
Re: Sorting long list of IPs. <jglascoe@giss.nasa.gov>
Re: Sorting long list of IPs. <uri@ibnets.com>
Re: Sorting long list of IPs. <Allan@due.net>
Re: Sorting long list of IPs. (Alastair)
Re: Sorting long list of IPs. <dboorstein@ixl.com>
Re: Sorting long list of IPs. <smiles@wfubmc.edu>
Re: Sorting long list of IPs. <jeffp@crusoe.net>
Re: Sorting long list of IPs. (M.J.T. Guy)
Re: Sorting long list of IPs. (M.J.T. Guy)
Re: Sorting long list of IPs. <uri@home.sysarch.com>
Special: Digest Administrivia (Last modified: 12 Dec 98 (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Mon, 22 Feb 1999 23:16:11 GMT
From: John@melon17.freeserve.co.uk (John )
Subject: Sort question
Message-Id: <36d2e4b2.17914716@news.freeserve.net>
I would like to sort several records
in a database based on an element
with a numerical value.
Any suggestions on how i do
this?
John
------------------------------
Date: Tue, 23 Feb 1999 12:30:09 GMT
From: NukeEmUp@ThePentagon.com (David Cantrell)
Subject: Re: Sort question
Message-Id: <36d29e2e.432789858@thunder>
On Mon, 22 Feb 1999 23:16:11 GMT, John@melon17.freeserve.co.uk (John )
enlightened us thusly:
>I would like to sort several records
>in a database based on an element
>with a numerical value.
[assuming that the word IN is important] ... you can't. The order in
which rows are stored in a database are undefined. It's not
necessarily the same order you put them in, and the order of rows can
change dramatically when you do something as simple as INSERT a new
row.
>Any suggestions on how i do
>this?
You can control the order in which records are spewed out by your
queries thus:
SELECT * FROM mytable ORDER BY myNumericField
This is not a perl question. Database questions such as this are
better dealt with in (for instance) comp.databases.[yourdb] or maybe
comp.databases.theory. Or even better, Dejanews has plenty of info on
this topic.
[Copying newsgroup posts to me by mail is considered rude]
--
David Cantrell, part-time Unix/perl/SQL/java techie
full-time chef/musician/homebrewer
http://www.ThePentagon.com/NukeEmUp
------------------------------
Date: Mon, 22 Feb 1999 23:44:34 GMT
From: John@melon17.freeserve.co.uk (John )
Subject: Re: Sort question
Message-Id: <36d4eafe.19527338@news.freeserve.net>
On Mon, 22 Feb 1999 23:38:09 GMT, alastair@calliope.demon.co.uk
(Alastair) wrote:
>John <John@melon17.freeserve.co.uk> wrote:
>>I would like to sort several records
>>in a database based on an element
>>with a numerical value.
>>
>>Any suggestions on how i do
>>this?
>
>Most Perl reference guides have a section on sorting techniques. You have given
>no detail at all on what the problem is. What have you tried?
I am trying to comprehend the basic process involved.
If for example you have name, age, address, and exam mark, and I want
to sort all the records on the basis of exam mark what is the process?
OK, you can easily sort the element exam mark, but then I presume you
have to move the whole record somehow?
John
------------------------------
Date: 23 Feb 1999 16:38:07 GMT
From: abigail@fnx.com (Abigail)
Subject: Re: Sort question
Message-Id: <7aulhf$20b$5@client2.news.psi.net>
John (John@melon17.freeserve.co.uk) wrote on MMI September MCMXCIII in
<URL:news:36d2e4b2.17914716@news.freeserve.net>:
<> I would like to sort several records
<> in a database based on an element
<> with a numerical value.
<>
<> Any suggestions on how i do
<> this?
Read the manual of your database server?
Abigail
--
perl -we 'print split /(?=(.*))/s => "Just another Perl Hacker\n";'
------------------------------
Date: Mon, 22 Feb 1999 23:38:09 GMT
From: alastair@calliope.demon.co.uk (Alastair)
Subject: Re: Sort question
Message-Id: <slrn7d3qlr.9p.alastair@calliope.demon.co.uk>
John <John@melon17.freeserve.co.uk> wrote:
>I would like to sort several records
>in a database based on an element
>with a numerical value.
>
>Any suggestions on how i do
>this?
Most Perl reference guides have a section on sorting techniques. You have given
no detail at all on what the problem is. What have you tried?
FYI, Tom C has a pretty comprehensive account of sorting ;
ftp://ftp-mirror.internap.com/pub/CPAN/doc/FMTEYEWTK/sort.html
HTH.
--
Alastair
work : alastair@psoft.co.uk
home : alastair@calliope.demon.co.uk
------------------------------
Date: Mon, 22 Feb 1999 17:59:38 -0600
From: "William H. Asquith" <asquith@macconnect.com>
Subject: Re: Sort question
Message-Id: <7asrm3$12d4@enews3.newsguy.com>
This is the coolest multiple array sorting that I've see to date.
#!/usr/bin/perl -w
@array1 = (1, 53, 34, 235, 21);
@array2 = qw(apples oranges junk and stuff);
@array3 = qw(fruit fruit meat -- more_stuff);
@index = sort { $array1[$a] <=> $array1[$b] } (0..$#array1);
@array1 = @array1[@index];
@array2 = @array2[@index];
@array3 = @array3[@index];
print "@array1 ","\n";
print "@array2 ","\n";
print "@array3 ","\n";
----------
In article <36d2e4b2.17914716@news.freeserve.net>,
John@melon17.freeserve.co.uk (John ) wrote:
> I would like to sort several records
> in a database based on an element
> with a numerical value.
>
> Any suggestions on how i do
> this?
>
> John
------------------------------
Date: Wed, 24 Feb 1999 11:10:30 -0500
From: The Skimin Family <mskimin@loraincounty.com>
Subject: sorting domain names by levels
Message-Id: <36D42475.A77BF14D@loraincounty.com>
Hello all,
I am lost with this one and hope someone can help.
I have a statistics package that gives me a list of dial-up, etc.
hosting domain names as follows:
<-- host list -->
ely-oh4-37.ix.netcom.com
ely-oh4-37.ix.netcom.com
ljk40.sat.net
ppp321.lr.centuryinter.net
net179025.hcv.com
ely-oh3-42.ix.netcom.com
<-- etc. host list -->
I would like to count how many times each level of the domain name
happens. Say for the above:
Level 1
.com = 4
.net = 2
Level 2
netcom.com = 4
centuryinter.net =1
hcv.com = 1
Level 3
ix.netcom.com = 4
lr.centuryinter.net = 1
net179025.hcv.com = 1
I have tried the above but I can't figure out how to sort the results
into numerical order by hits.
Any help would be great. Following is what I have tried.
sub level2 {
$form_data{'level'} = 1;
$query = "select host from lc_hits";
$sth = $dbh->query("$query");
while (@data = $sth->fetchrow()) {
# make sure $data[0] actually has a domain name
if ($data[0] ne "") {
# Create $use_site for specific domain name level
@site = reverse split (/\./, $data[0]);
if ($form_data{'level'} == 3) {
$use_site = "$site[2]\.$site[1]\.$site[0]";
}
elsif ($form_data{'level'} == 2) {
$use_site = "$site[1]\.$site[0]";
}
else {
$use_site = "\.$site[0]";
}
# count hits
$hit_amount{$use_site}++;
# list hosts for foreach
$host_list =~ s/$use_site,//g;
$host_list .= "$use_site,";
}
}
@split_hosts = split (/,/, $host_list);
foreach $host_name (@split_hosts) {
print "$host_name = $hit_amount{$host_name}\n<br>";
}
}
The result was
<br>.Com = 2
<br>.COM = 1
<br>.no = 1
<br>.bh = 1
<br>.CA = 2
<br>.pt = 2
<br>.de = 3
<br>.arpa = 3
<br>.se = 3
<br>.ar = 3
<br>.fr = 2
<br>.nz = 1
<br>.ie = 1
<br>.in = 6
Thus how do I sort the above in order?
Thank you in advance for any and all help.
Mike Skimin, Webmaster
Emerge Inc.
http://www.LorainCounty.com
http://www.EmergeInc.com
------------------------------
Date: Wed, 24 Feb 1999 17:40:55 -0500
From: tadmc@metronet.com (Tad McClellan)
Subject: Re: sorting domain names by levels
Message-Id: <n5v1b7.oic.ln@magna.metronet.com>
The Skimin Family (mskimin@loraincounty.com) wrote:
: I would like to count how many times each level of the domain name
: happens. Say for the above:
: I have tried the above but I can't figure out how to sort the results
: into numerical order by hits.
--------------------------------------
#!/usr/bin/perl -w
use strict;
my %cnt;
while (<DATA>) {
chomp;
foreach my $domain_name ( split_parts($_) ) {
my $level = $domain_name =~ tr/././ + 1;
$cnt{$level}{$domain_name}++;
}
}
foreach my $level (sort {$a <=> $b} keys %cnt ) {
print "Level $level:\n";
foreach my $domain_name ( sort {$cnt{$level}->{$b} <=> $cnt{$level}->{$a}}
keys %{$cnt{$level}} ) {
print "$domain_name = $cnt{$level}->{$domain_name}\n";
}
print "\n";
}
sub split_parts {
my($domain) = @_;
my @parts; # return value
my @pieces = reverse split /\./, $domain;
foreach my $length (0 .. $#pieces) {
push @parts, join '.', reverse @pieces[0..$length];
}
return @parts;
}
__DATA__
ely-oh4-37.ix.netcom.com
ely-oh4-37.ix.netcom.com
ljk40.sat.net
ppp321.lr.centuryinter.net
net179025.hcv.com
ely-oh3-42.ix.netcom.com
--------------------------------------
--
Tad McClellan SGML Consulting
tadmc@metronet.com Perl programming
Fort Worth, Texas
------------------------------
Date: Tue, 23 Feb 1999 15:08:37 -0800
From: "aaron" <aaron@tyc.net>
Subject: sorting info from data files
Message-Id: <36d3a9d7.0@news1.jps.net>
I have a pipe delimited datafile that looks like
$NAME,$DATE,$CREDIT
That data might be:
joe123|Feb 01 1999|15
tanya|Feb 01 1999|15
bob8722|Feb 01 1999|10
bob8722|Feb 02 1999|10
bob8722|Feb 02 1999|10
tanya|Feb 03 1999|20
I want to output the data so each different $NAME in the data file is
organized into one line of information that displays a $total_credits
variable and $total_appearances variable for each $NAME in the file. Using
the data above, it would look like:
bob8722 - 3 - 30
tanya - 2 - 35
joe123 - 1 - 15
The first line of output above shows that bob8722 appeared 3 times in the
data file and has earned a total of 30 credits...and so on.
Also, how might the output be sorted so he/she that appears more times in
the data file is closer to the top?
Thank you so much for your help!
Aaron
------------------------------
Date: Tue, 23 Feb 1999 19:22:41 -0500
From: Jay Glascoe <jglascoe@giss.nasa.gov>
To: aaron <aaron@tyc.net>
Subject: Re: sorting info from data files
Message-Id: <36D34650.1AB04D46@giss.nasa.gov>
aaron wrote:
>
> I have a pipe delimited datafile that looks like
>
> $NAME,$DATE,$CREDIT
>
> That data might be:
>
> joe123|Feb 01 1999|15
> tanya|Feb 01 1999|15
> bob8722|Feb 01 1999|10
> bob8722|Feb 02 1999|10
> bob8722|Feb 02 1999|10
> tanya|Feb 03 1999|20
>
> I want to output the data so each different $NAME in the data file is
> organized into one line of information that displays a $total_credits
> variable and $total_appearances variable for each $NAME in the file. Using
> the data above, it would look like:
>
> bob8722 - 3 - 30
> tanya - 2 - 35
> joe123 - 1 - 15
>
my %hash = ();
while (<FH>)
{
chomp;
my ($name, $date, $credits) = split m#\|#;
push @{ $hash{$name} }, $credits;
}
my @sorted_names = sort keys %hash;
for $name (@sorted_names)
{
my @credit_list = @{ $hash{$name} };
my $total_visits = @credit_list;
my $total_credits = 0;
for (@credit_list) { $total_credits += $_ }
print "$name - $total_visits - $total_credits\n";
}
> The first line of output above shows that bob8722 appeared 3 times in the
> data file and has earned a total of 30 credits...and so on.
>
> Also, how might the output be sorted so he/she that appears more times in
> the data file is closer to the top?
mmm. Schwartzian Transform? (I think that's what this is:)
# substitute this line for the earlier sort
my @sorted_names = map { $_->[0] }
sort { $b->[1] <=> $a->[1] }
map { [ $_, scalar @{ $hash{$_} } ] }
keys %hash;
> Thank you so much for your help!
> Aaron
--
"Yes, you can think of almost everything as a function,
but this may upset your wife."
-- Larry Wall
------------------------------
Date: Tue, 23 Feb 1999 14:10:23 -0500
From: tadmc@metronet.com (Tad McClellan)
Subject: Re: sorting info from data files
Message-Id: <veuua7.gu5.ln@magna.metronet.com>
aaron (aaron@tyc.net) wrote:
: I have a pipe delimited datafile that looks like
: I want to output the data so each different $NAME in the data file is
: organized into one line of information that displays a $total_credits
: variable and $total_appearances variable for each $NAME in the file. Using
: the data above, it would look like:
: Also, how might the output be sorted so he/she that appears more times in
: the data file is closer to the top?
----------------------------
#!/usr/bin/perl -w
use strict;
my %count; # hash of list would be better than parallel hashes
my %credit;
while (<DATA>) {
chomp;
my($name, $date, $credit) = split /\|/;
$count{$name}++;
$credit{$name} += $credit;
}
foreach ( sort {$count{$b} <=> $count{$a}} keys %count) {
print "$_ - $count{$_} - $credit{$_}\n";
}
__DATA__
joe123|Feb 01 1999|15
tanya|Feb 01 1999|15
bob8722|Feb 01 1999|10
bob8722|Feb 02 1999|10
bob8722|Feb 02 1999|10
tanya|Feb 03 1999|20
----------------------------
--
Tad McClellan SGML Consulting
tadmc@metronet.com Perl programming
Fort Worth, Texas
------------------------------
Date: Wed, 24 Feb 1999 12:11:52 -0500
From: Jay Glascoe <jglascoe@giss.nasa.gov>
To: aaron <aaron@tyc.net>
Subject: Re: sorting info from data files
Message-Id: <36D432D8.CF295FB9@giss.nasa.gov>
[courtesy copy of post sent to Aaron]
Jay Glascoe wrote:
>
> # substitute this line for the earlier sort
> my @sorted_names = map { $_->[0] }
> sort { $b->[1] <=> $a->[1] }
> map { [ $_, scalar @{ $hash{$_} } ] }
> keys %hash;
you know, I've really gotta stop smoking crack prior
to answering questions on usenet. ;)
my @sorted_names = sort { @$hash[$b] <=> @$hash[$a] } keys %hash;
Jay Glascoe
--
"Even if you do learn to speak correct English,
whom are you going to speak it to?"
--Clarence Darrow
------------------------------
Date: Wed, 24 Feb 1999 17:20:56 -0500
From: Ala Qumsieh <aqumsieh@matrox.com>
Subject: Re: sorting info from data files
Message-Id: <x3yyalncuk7.fsf@tigre.matrox.com>
"aaron" <aaron@tyc.net> writes:
> joe123|Feb 01 1999|15
> tanya|Feb 01 1999|15
> bob8722|Feb 01 1999|10
> bob8722|Feb 02 1999|10
> bob8722|Feb 02 1999|10
> tanya|Feb 03 1999|20
>
> I want to output the data so each different $NAME in the data file is
> organized into one line of information that displays a $total_credits
> variable and $total_appearances variable for each $NAME in the file. Using
> the data above, it would look like:
>
> bob8722 - 3 - 30
> tanya - 2 - 35
> joe123 - 1 - 15
Warning: untested code
my (@ar, %hash);
while (<DATA>) { # assume input is coming from there
chomp;
@ar = split /|/;
if (exists $hash{$ar[0]}) {
$hash{$ar[0]}{credits} += $ar[2];
$hash{$ar[0]}{app}++;
} else {
$hash{$ar[0]}{credits} = $ar[2];
$hash{$ar[0]}{app} = 1;
}
}
for my $key (sort { $hash{$a}{app} <=> $hash{$b}{app} } keys %hash) {
print "$key - $hash{$key}{app} - $hash{$key}{credits}\n";
}
HTH,
Ala
------------------------------
Date: Thu, 25 Feb 1999 04:36:02 GMT
From: Rick Delaney <rick.delaney@home.com>
Subject: Re: sorting info from data files
Message-Id: <36D4D51D.987BF20@home.com>
[posted & mailed]
Jay Glascoe wrote:
>
> you know, I've really gotta stop smoking crack prior
> to answering questions on usenet. ;)
You might want to lay off the acid too. :-)
> my @sorted_names = sort { @$hash[$b] <=> @$hash[$a] } keys %hash;
my @sorted_names = sort {
@{ $hash{$b} } <=> @{ $hash{$a} }
} keys %hash;
--
Rick Delaney
rick.delaney@home.com
------------------------------
Date: Thu, 25 Feb 1999 17:24:52 GMT
From: droby@copyright.com
Subject: Re: sorting info from data files
Message-Id: <7b410o$5vo$1@nnrp1.dejanews.com>
In article <x3yyalncuk7.fsf@tigre.matrox.com>,
Ala Qumsieh <aqumsieh@matrox.com> wrote:
>
> Warning: untested code
>
Why? How much longer would it take to test it. You might even find the
missing toothpick.
> my (@ar, %hash);
>
> while (<DATA>) { # assume input is coming from there
> chomp;
> @ar = split /|/;
@ar = split /\|/;
> if (exists $hash{$ar[0]}) {
> $hash{$ar[0]}{credits} += $ar[2];
> $hash{$ar[0]}{app}++;
> } else {
> $hash{$ar[0]}{credits} = $ar[2];
> $hash{$ar[0]}{app} = 1;
> }
> }
>
> for my $key (sort { $hash{$a}{app} <=> $hash{$b}{app} } keys %hash) {
> print "$key - $hash{$key}{app} - $hash{$key}{credits}\n";
> }
>
The sort order is also reversed from his example, so maybe you should have
switched $a and $b.
--
Don Roby
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: Thu, 25 Feb 1999 10:48:12 -0800
From: lr@hpl.hp.com (Larry Rosler)
Subject: Re: sorting info from data files
Message-Id: <MPG.113f3acb8dea204698968b@nntp.hpl.hp.com>
[Posted and a courtesy copy mailed.]
In article <x3yyalncuk7.fsf@tigre.matrox.com> on Wed, 24 Feb 1999
17:20:56 -0500, Ala Qumsieh <aqumsieh@matrox.com> says...
...
> @ar = split /|/;
> if (exists $hash{$ar[0]}) {
> $hash{$ar[0]}{credits} += $ar[2];
> $hash{$ar[0]}{app}++;
> } else {
> $hash{$ar[0]}{credits} = $ar[2];
> $hash{$ar[0]}{app} = 1;
> }
In addition to the error in the split regex pointed out by Don Roby, one
might also observe that these initializations are superfluous (wordy and
error-prone). All that is needed is:
$hash{$ar[0]}{credits} += $ar[2];
$hash{$ar[0]}{app}++;
A bug in earlier perls generated warning messages about uninitialized
variables, but that has been fixed.
--
Larry Rosler
Hewlett-Packard Company
http://www.hpl.hp.com/personal/Larry_Rosler/
lr@hpl.hp.com
------------------------------
Date: Sun, 21 Feb 1999 15:36:27 -0500
From: Steve Miles <smiles@wfubmc.edu>
Subject: Sorting long list of IPs.
Message-Id: <36D06E4B.418FDDB6@wfubmc.edu>
I have a text file that is a long list (10,000+) pairs of data delimited
by a pipe: "$ip|username".
What I want to do is get the count of unique IP addresses - but without
pushing them all into an array first.
Currently I push all the IP's into an array - sort them - then:
foreach $ip (@ips) {
if ($ip eq $lastip) { push (@newips, $ip); }
$lastip = $ip;
}
$num_of_unique_ips = "@newips";
Is there a way to get the count of unique IPs without using an array?
=============================================
Steve Miles (smiles@wfubmc.edu)
Wake Forest University School of Medicine
5019 Hanes, Medical Center Blvd.
Winston-Salem, NC 27157
Phone: 336.716.0454 FAX: 336.716.7200
=============================================
------------------------------
Date: Tue, 23 Feb 1999 08:58:43 -0500
From: "Allan M. Due" <Allan@due.net>
Subject: Re: Sorting long list of IPs.
Message-Id: <7aubqa$t5c$1@camel0.mindspring.com>
Uri Guttman wrote in message <39d832qchj.fsf@ibnets.com>...
:>>>>> "SM" == Steve Miles <smiles@wfubmc.edu> writes:
:that is a very poor solution to your question.
: SM> while (<FH>)
: SM> {
: SM> my ($ip, $username) = split /[|]/;
: SM> $hash{$ip} = $username;
:why save the username, when you don't use them and they get overwritten
:with each duplicate IP? why even get the username from the split?
: SM> }
: SM> my (@unique_ips) = sort keys %hash;
:why sort the keys when all you do is get the count of keys?
: SM> my $num_unique_ips = @unique_ips;
:why assign the keys to an array to get the count when keys in a scalar
:context will give you the count?
:this is much simpler and probably a lot faster.
:
:while (<FH>) {
: $hash{ (split( /\|/, $_, 1) )[0] }++ ;
:}
What am I missing? In this case doesn't the limit of 1 force there to be
only one field produced from the split, and therefor we force both ip and
username into the key? If we have the same ip and different users we won't
track the number of unique ips.
my $pair = 'ip|username';
my @out = split(/\|/,$pair,1);
print "@out";
gives
ip|username
AmD
--
$email{'Allan M. Due'} = 'Allan@Due.net';
--random quote --
An old pond-
The sound of the water
When the frog jumps in
Basho
------------------------------
Date: Mon, 22 Feb 1999 16:21:55 -0500
From: Jay Glascoe <jglascoe@giss.nasa.gov>
To: Steve Miles <smiles@wfubmc.edu>
Subject: Re: Sorting long list of IPs.
Message-Id: <36D1CA73.A4394625@giss.nasa.gov>
[courtesy copy of post sent to Steve]
hi Steve,
Steve Miles wrote:
>
> I have a text file that is a long list (10,000+) pairs of data delimited
> by a pipe: "$ip|username".
> What I want to do is get the count of unique IP addresses - but without
> pushing them all into an array first.
>
> Currently I push all the IP's into an array - sort them - then:
>
> foreach $ip (@ips) {
> if ($ip eq $lastip) { push (@newips, $ip); }
> $lastip = $ip;
> }
> $num_of_unique_ips = "@newips";
>
> Is there a way to get the count of unique IPs without using an array?
>
while (<FH>)
{
my ($ip, $username) = split /[|]/;
$hash{$ip} = $username;
}
my (@unique_ips) = sort keys %hash;
my $num_unique_ips = @unique_ips;
Jay Glascoe
--
"C" is for cookie. That's good enough for me.
--Cookie Monster
------------------------------
Date: Mon, 22 Feb 1999 17:03:00 -0500
From: "Ken Hirsch" <kenhirsch@myself.com>
Subject: Re: Sorting long list of IPs.
Message-Id: <7ask5k$4ul$1@fir.prod.itd.earthlink.net>
Steve Miles wrote:
>I have a text file that is a long list (10,000+) pairs of data delimited
>by a pipe: "$ip|username".
>What I want to do is get the count of unique IP addresses - but without
>pushing them all into an array first.
You can use the Unix file sort instead:
$count = `cut -f 1 -d '|' ipfile | sort -u | wc -l`;
$count =~ s/\s//g;
Ken Hirsch
------------------------------
Date: Mon, 22 Feb 1999 17:02:00 -0500
From: Jay Glascoe <jglascoe@giss.nasa.gov>
To: jglascoe@giss.nasa.gov
Subject: Re: Sorting long list of IPs.
Message-Id: <36D1D3D8.27EFB197@giss.nasa.gov>
Jay Glascoe wrote:
>
> while (<FH>)
> {
> my ($ip, $username) = split /[|]/;
> $hash{$ip} = $username;
> }
I like this better:
while (<FH>)
{
chomp();
my ($ip, $username) = split m#\|#;
if (defined ($aref = $hash{$ip}))
{
push @$aref, $username;
}
else
{
$hash{$ip} = [$username];
}
# if you care about the order in which
# the "ip"s occur in your file, then
push @ips_seen, $ip;
}
--
"Even if you do learn to speak correct English,
whom are you going to speak it to?"
--Clarence Darrow
------------------------------
Date: 22 Feb 1999 17:50:48 -0500
From: Uri Guttman <uri@ibnets.com>
To: Steve Miles <smiles@wfubmc.edu>
Subject: Re: Sorting long list of IPs.
Message-Id: <39d832qchj.fsf@ibnets.com>
>>>>> "SM" == Steve Miles <smiles@wfubmc.edu> writes:
that is a very poor solution to your question.
SM> while (<FH>)
SM> {
SM> my ($ip, $username) = split /[|]/;
SM> $hash{$ip} = $username;
why save the username, when you don't use them and they get overwritten
with each duplicate IP? why even get the username from the split?
SM> }
SM> my (@unique_ips) = sort keys %hash;
why sort the keys when all you do is get the count of keys?
SM> my $num_unique_ips = @unique_ips;
why assign the keys to an array to get the count when keys in a scalar
context will give you the count?
this is much simpler and probably a lot faster.
while (<FH>) {
$hash{ (split( /\|/, $_, 1) )[0] }++ ;
}
$unique = keys %hash ;
hth,
uri
--
Uri Guttman Hacking Perl for Ironbridge Networks
uri@sysarch.com uri@ironbridgenetworks.com
------------------------------
Date: Mon, 22 Feb 1999 16:35:45 -0500
From: "Allan M. Due" <Allan@due.net>
Subject: Re: Sorting long list of IPs.
Message-Id: <7asi78$o7j$1@camel19.mindspring.com>
Steve Miles wrote in message <36D06E4B.418FDDB6@wfubmc.edu>...
:I have a text file that is a long list (10,000+) pairs of data delimited
:by a pipe: "$ip|username".
:What I want to do is get the count of unique IP addresses - but without
:pushing them all into an array first.
:Currently I push all the IP's into an array - sort them - then:
:foreach $ip (@ips) {
: if ($ip eq $lastip) { push (@newips, $ip); }
: $lastip = $ip;
:}
:$num_of_unique_ips = "@newips";
:Is there a way to get the count of unique IPs without using an array?
How about just making them keys of a hash and then geting the number of
keys?
HTH
AmD
------------------------------
Date: Mon, 22 Feb 1999 21:32:22 GMT
From: alastair@calliope.demon.co.uk (Alastair)
Subject: Re: Sorting long list of IPs.
Message-Id: <slrn7d3ja1.5a.alastair@calliope.demon.co.uk>
Steve Miles <smiles@wfubmc.edu> wrote:
>I have a text file that is a long list (10,000+) pairs of data delimited
>by a pipe: "$ip|username".
>What I want to do is get the count of unique IP addresses - but without
>pushing them all into an array first.
Good advice for anyone who needs to consider 'uniqueness' would be to think of a
hash. Hash keys are, by definition, unique. So, why not add your IP numbers to a
hash ;
ip_hash{$ip}++;
Any key with a value > 1 is not unique. Those with a value of 1 are.
HTH.
--
Alastair
work : alastair@psoft.co.uk
home : alastair@calliope.demon.co.uk
------------------------------
Date: Mon, 22 Feb 1999 16:46:09 -0500
From: Dan Boorstein <dboorstein@ixl.com>
Subject: Re: Sorting long list of IPs.
Message-Id: <36D1D021.37F7A37B@ixl.com>
assuming that the data is accessible from the file handle DATA and that
it is contained cleanly within the file, then you could use:
$unique = keys %{ { map +(split '\|'), <DATA> } };
print $unique;
this reads in the data from the file, splitting on the pipe character,
assigning the ips as keys in an anonymous hash and the usernames as
throw-away values. this anonymous hash is dereferenced in place, as
the argument to 'keys', which in a scalar context yields the number
of keys.
no arrays, no sorting, no named variables but the one you wanted.
cheers,
dan boorstein
Steve Miles wrote:
>
> I have a text file that is a long list (10,000+) pairs of data delimited
> by a pipe: "$ip|username".
> What I want to do is get the count of unique IP addresses - but without
> pushing them all into an array first.
>
> Currently I push all the IP's into an array - sort them - then:
>
> foreach $ip (@ips) {
> if ($ip eq $lastip) { push (@newips, $ip); }
> $lastip = $ip;
> }
> $num_of_unique_ips = "@newips";
>
> Is there a way to get the count of unique IPs without using an array?
>
> =============================================
> Steve Miles (smiles@wfubmc.edu)
> Wake Forest University School of Medicine
> 5019 Hanes, Medical Center Blvd.
> Winston-Salem, NC 27157
> Phone: 336.716.0454 FAX: 336.716.7200
> =============================================
------------------------------
Date: Sun, 21 Feb 1999 17:19:54 -0500
From: Steve Miles <smiles@wfubmc.edu>
Subject: Re: Sorting long list of IPs.
Message-Id: <36D0868A.20D6E4F9@wfubmc.edu>
Thanks everyone, some great replies...here's the answer I used:
while (<FH>)
{
my ($ip, $username) = split /[|]/;
$hash{$ip} = $username;
}
my (@unique_ips) = sort keys %hash;
my $num_unique_ips = @unique_ips;
Jay Glascoe <jglascoe@giss.nasa.gov>
Thanks Jay and everyone else!
=============================================
Steve Miles (smiles@wfubmc.edu)
Wake Forest University School of Medicine
5019 Hanes, Medical Center Blvd.
Winston-Salem, NC 27157
Phone: 336.716.0454 FAX: 336.716.7200
=============================================
------------------------------
Date: Mon, 22 Feb 1999 18:19:11 -0500
From: evil Japh <jeffp@crusoe.net>
Subject: Re: Sorting long list of IPs.
Message-Id: <Pine.GSO.3.96.990222181138.19973D-100000@crusoe.crusoe.net>
> Currently I push all the IP's into an array - sort them - then:
>
> foreach $ip (@ips) {
> if ($ip eq $lastip) { push (@newips, $ip); }
> $lastip = $ip;
> }
> $num_of_unique_ips = "@newips";
That code is erroneous; $num_of_unique_ips will not get the number of
elements in the @newips array; rather, it will get a space-separated
(assuming you've not touched $") string of all the elements in @newips.
This code, employing a hash, should do the trick:
# Refer to:
# perlfaq4
# How can I extract just the unique elements of an array?
undef %seen;
$seen{$_}++ for @ips; # only works in perl5.005 and up
for (@ips){ $seen{$_}++; } # this works for perl5.004, for instance
$num_of_unique_ips = keys %seen;
Hope this clears up the matter some.
--
Jeff Pinyan (jeffp@crusoe.net)
www.crusoe.net/~jeffp
Crusoe Communications, Inc.
973-882-1022
www.crusoe.net
------------------------------
Date: 23 Feb 1999 00:45:51 GMT
From: mjtg@cus.cam.ac.uk (M.J.T. Guy)
Subject: Re: Sorting long list of IPs.
Message-Id: <7astnv$mr3$1@pegasus.csx.cam.ac.uk>
Jay Glascoe <jglascoe@giss.nasa.gov> wrote:
>
>while (<FH>)
>{
> my ($ip, $username) = split /[|]/;
> $hash{$ip} = $username;
Why bother to store the username when it's never used? I'd make those
two lines
my ($ip) = split /[|]/;
$hash{$ip}++;
Or, to be more obscure
$hash{(split /[|]/)[0]}++;
>}
>
>my (@unique_ips) = sort keys %hash;
>my $num_unique_ips = @unique_ips;
Why are you sorting something when you only want to count? And why the
spurious array copy? Replace those last two lines with
my $num_unique_ips = keys %hash;
Mike Guy
------------------------------
Date: 23 Feb 1999 01:04:14 GMT
From: mjtg@cus.cam.ac.uk (M.J.T. Guy)
Subject: Re: Sorting long list of IPs.
Message-Id: <7asuqe$np2$1@pegasus.csx.cam.ac.uk>
Dan Boorstein <dboorstein@ixl.com> wrote:
>assuming that the data is accessible from the file handle DATA and that
>it is contained cleanly within the file, then you could use:
>
>$unique = keys %{ { map +(split '\|'), <DATA> } };
>print $unique;
>
>no arrays, no sorting, no named variables but the one you wanted.
Pedantically correct - no arrays. But you *are* building a list of
all the input lines, contrary to Steve's intent.
>Steve Miles wrote:
>> What I want to do is get the count of unique IP addresses - but without
>> pushing them all into an array first.
Mike Guy
------------------------------
Date: 23 Feb 1999 23:25:48 -0500
From: Uri Guttman <uri@home.sysarch.com>
Subject: Re: Sorting long list of IPs.
Message-Id: <x7n224julv.fsf@home.sysarch.com>
>>>>> "AMD" == Allan M Due <Allan@due.net> writes:
AMD> :while (<FH>) {
AMD> : $hash{ (split( /\|/, $_, 1) )[0] }++ ;
^
AMD> :}
that should be 2. my bad. i keep forgetting that a max split count of 1
is motly a noo-op and useless.
AMD> What am I missing? In this case doesn't the limit of 1 force
AMD> there to be only one field produced from the split, and therefor
AMD> we force both ip and username into the key? If we have the same
AMD> ip and different users we won't track the number of unique ips.
uri
--
Uri Guttman ----------------- SYStems ARCHitecture and Software Engineering
Perl Hacker for Hire ---------------------- Perl, Internet, UNIX Consulting
uri@sysarch.com ------------------------------------ http://www.sysarch.com
The Best Search Engine on the Net ------------- http://www.northernlight.com
------------------------------
Date: 12 Dec 98 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Special: Digest Administrivia (Last modified: 12 Dec 98)
Message-Id: <null>
Administrivia:
Well, after 6 months, here's the answer to the quiz: what do we do about
comp.lang.perl.moderated. Answer: nothing.
]From: Russ Allbery <rra@stanford.edu>
]Date: 21 Sep 1998 19:53:43 -0700
]Subject: comp.lang.perl.moderated available via e-mail
]
]It is possible to subscribe to comp.lang.perl.moderated as a mailing list.
]To do so, send mail to majordomo@eyrie.org with "subscribe clpm" in the
]body. Majordomo will then send you instructions on how to confirm your
]subscription. This is provided as a general service for those people who
]cannot receive the newsgroup for whatever reason or who just prefer to
]receive messages via e-mail.
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.misc (and this Digest), send your
article to perl-users@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V8 Issue 4999
**************************************