in reply to How to sort IP addresses

IP addresses (v4, that is) are four bytes, separated by dots. A sequence like 123.456.789.12 is no valid IP address, since 456 and 789 overflow a byte, which can be 0..255. You can sort IP addresses easily converting them into numbers. There are several ways to do that. You can e.g use the inet_aton routine form Socket:
use Socket; my $ip = '127.0.0.1'; print unpack('N', inet_aton($ip)),"\n"; __END__ 2130706433

An equivalent would be

my $ip = '127.0.0.1'; print unpack('N', pack 'C*', split /\./, $ip),"\n"; __END__ 2130706433

Now, for sorting them, you don't want to split / pack / unpack them for every comparison of two items during the sort. So make an list of anonymous arrays holding each [ $numeric, $ip ], sort them via the first element and pull out the second from the sorted list:

use Socket; chomp(my @ips = <DATA>); my @sorted = map { $_->[1] } # pull out second element sort {$a->[0] <=> $b->[0]} # sort list of arrays by first +element map { [ # construct an anonymous array +with a unpack('N',inet_aton($_)), # transformed IP address $_ # and IP address ] } @ips; # your input list print "$_\n" for @sorted; __DATA__ 192.168.10.15 10.24.13.88 172.16.254.13 10.24.13.89 89.67.128.254

Result:

10.24.13.88 10.24.13.89 89.67.128.254 172.16.254.13 192.168.10.15

See Socket, map, sort.

Sorting IPs might well be a FAQ...

<update>

Wrapped inet_aton in unpack, s/chop/chomp/. Thanks, ikegami.

</update>

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: How to sort IP addresses
by ikegami (Patriarch) on Jan 30, 2007 at 07:03 UTC

    I have two bug fixes and a speed enhancement for you.

    inet_aton doesn't return a number, yet you sort numerically.
    sort { $a->[0] <=> $b->[0] }
    should be
    sort { $a->[0] cmp $b->[0] }

    chop could drop the last char of the data in the file. (e.g. The file could be "10.0.0.1\n10.0.0.2\n10.0.0.5".) Use chomp instead of chop.

    It's much faster to avoid creating numerous anonymous arrays and using the default lexical sort, and it's trivial to do here since inet_aton returns a fixed length string. See my post for details.