Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Summarizing an array of IP's

by carric (Beadle)
on Jan 06, 2004 at 21:17 UTC ( [id://319246]=perlquestion: print w/replies, xml ) Need Help??

carric has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to think of a good way to do this, and I'm struggling.

I have an array of IP's that is like this:

10.0.0.1
10.0.0.2
10.0.0.3
192.168.1.5
192.168.1.6
192.168.10.3
192.168.10.4
192.168.10.5

What I want is it to print out:

10.0.0: 3 nodes
192.168.1: 2 nodes
192.168.10: 3 nodes

Thank you in advance for some ideas.

Replies are listed 'Best First'.
Re: Summarizing an array of IP's
by exussum0 (Vicar) on Jan 06, 2004 at 21:28 UTC
    Update: Or replace with whatever array you love too :)

    Replace DATA with <> or whatever file handle you love.

    use strict; use warnings; my %ips = (); map { $ips{ join('.',(split('\.',$_,4))[0..2] ) }++ } <DATA>; print "$_ has $ips{$_} nodes\n" foreach sort keys %ips; __DATA__ 10.10.10.1 10.10.10.2 10.10.10.3 10.10.12.1

    Play that funky music white boy..
Re: Summarizing an array of IP's
by thelenm (Vicar) on Jan 06, 2004 at 21:49 UTC
    my %h; /^(\d+\.\d+\.\d+)/ and ++$h{$1} for <DATA>; print "$_: $h{$_} nodes\n" for sort keys %h; __DATA__ 10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.4 192.168.10.5

    -- Mike

    --
    XML::Simpler does not require XML::Parser or a SAX parser. It does require File::Slurp.
    -- grantm, perldoc XML::Simpler

Re: Summarizing an array of IP's
by Enlil (Parson) on Jan 06, 2004 at 21:54 UTC
    If what you mean by node is unique values:
    use strict; use warnings; my %ips; my @array = qw ( 10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.4 192.168.10.5 10.0.0.1); foreach (@array) { $ips{$1}{$2} = undef if /([\d.]+)\.(\d+)$/; } foreach ( keys %ips ) { my $keys = keys %{$ips{$_}}; print "$_: $keys nodes\n" }

    If by nodes you meant values appearing regardless of possible duplication:

    use strict; use warnings; my %ips; my @array = qw ( 10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.4 192.168.10.5 10.0.0.1); foreach (@array) { $ips{$1}++ if /([\d.]+)\.(\d+)$/; } foreach ( keys %ips ) { print "$_: $ips{$_} nodes\n" }

    (Note the different value of 10.0.0 caused by the extra 10.0.0.1 in the array)

    -enlil

      This looks like the closest to what I am after. I apologize for not being clearer.. I want to produce a report of how many network nodes there are per class C subnet (this is not a class C, in fact I scanned a class B, but the data is more digestable if I just show the "class C chunks" that contained live hosts).

      Thanks a lot for the help!!

Re: Summarizing an array of IP's
by pg (Canon) on Jan 06, 2004 at 23:47 UTC

    We can use some of the standard functions loaded by "Socket" module to handle ip addresses:

    use Socket; use strict; use warnings; my %stat; my @addr = qw(10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.4 192.168.10.5); $stat{inet_ntoa(substr(inet_aton($_), 0, 3) . "\0")} ++ foreach (@addr +); print "$_ has $stat{$_} nodes\n" foreach (keys %stat);
      This code doesn't work when copied and pasted out. I wasn't sure which module to use for the IP's though. Thank you.

        Make sure that you have "use Socket" included as showed in demo code. That's the module where you get inet_aton() and inet_ntoa(). (Be careful, this is not the same module as "IO::Socket".)

        The code was actually tested and worked. Here is the testing result:

        192.168.10.0 has 3 nodes 192.168.1.0 has 2 nodes 10.0.0.0 has 3 nodes

        Update:

        Read carric's reply. carric, whenever you copy and paste code, you should remove those '+' signs indicating line breaks. Those are not part of the original code.

Re: Summarizing an array of IP's
by qq (Hermit) on Jan 07, 2004 at 16:27 UTC

    One more for you:

    #!/usr/bin/perl use strict; use warnings; my %nodes; while ( <DATA> ) { chomp; s/\.[^\.]$//; $nodes{ $_ }++; } foreach ( sort keys %nodes ) { print "$_ $nodes{$_} nodes\n"; } __DATA__ 10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.4 192.168.10.5
Re: Summarizing an array of IP's
by johndageek (Hermit) on Jan 07, 2004 at 23:03 UTC
    Just a little fun, assuming (gasp) sorted input.
    #!/usr/bin/perl use strict; use warnings; my $pip=""; my $ctr=0; while (<DATA>) { chomp; s/\.\d+$//; if ($pip ne $_ && $pip ne"") { print "$pip has $ctr entries\n"; $ctr=1; } else { $ctr++; } $pip=$_; } __DATA__ 10.0.0.1 10.0.0.2 10.0.0.3 192.168.1.5 192.168.1.6 192.168.10.3 192.168.10.46 192.168.10.5
    Enjoy,
    dageek
Re: Summarizing an array of IP's
by Elijah (Hermit) on Jan 06, 2004 at 21:37 UTC
    I am not sure if I am over simplifying what you want to accomplish or just dont understand it in the first place but iw would be relatively simple to append "nodes" to each item in the array.

    foreach $ip (@array) { print $ip." nodes"; }
      He wants to know what class c's there are and how many ip's are in each class c.

      Play that funky music white boy..
        Ahh yes I did not see the (:) colon in the desired output.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://319246]
Approved by phydeauxarff
Front-paged by PERLscienceman
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-16 10:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found