http://www.perlmonks.org?node_id=88295

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

The format of the file is like this:
1.2.3.4,1.2.3.255,USA
2.3.4.0,2.3.4.25,USA
124.2.3.0,124.2.3.255,Argentina
I need to sort the file based on IP Address, country wise
How can I do this?

Originally posted as a Categorized Question.

  • Comment on How do I sort a file with IP Addresses and another text column?

Replies are listed 'Best First'.
Re: How do I sort a file with IP Addresses and another text column
by tadman (Prior) on Jun 15, 2001 at 20:46 UTC
    use Socket qw [inet_aton]; sub squish { my($ip_lo,$ip_hi,$name) = split (//,$_[0]); return $name.inet_aton($ip_lo).inet_aton($ip_hi); } @sorted = sort { squish($a) cmp squish($b) } @unsorted;
    The inet_aton function returns four bytes, the value of the IP address in network order, which sorts properly using an ASCII sort. The Socket module is standard with Perl.
Re: How do I sort a file with IP Addresses and another text column
by I0 (Priest) on Jun 15, 2001 at 11:09 UTC
    print map{sprintf(("%d.%d.%d.%d,"x2)."%s\n",(split/,/)[1..8,0])} sort map{sprintf"%s".",%3d"x8,(split/\W/)[8,0..7]} <DATA> __DATA__ 1.2.3.4,1.2.3.255,USA 2.3.4.0,2.3.4.25,USA 124.2.3.0,124.2.3.255,Argentina
      I'd just like to add to this excellent answer...If you've just got a list of IP addresses to sort -- not two IP addresses plus a country -- here's how you'd do it:

      print map{sprintf(("%d.%d.%d.%d")."%s\n",(split/,/)\[0..3\])} sort map{sprintf"%3d,"x4,(split/\W/)\[0..3\]}

      It took a lot of scratching my head to adapt this, so I thought I'd save the next person the trouble. Hope it's useful!

Re: How do I sort a file with IP Addresses and another text column
by mikeB (Friar) on Jun 14, 2001 at 19:03 UTC
    Try splitting the IP and reformatting it into a fixed length string: 001.002.003.004. Then a text sort should work.

    Originally posted as a Categorized Answer.

Re: How do I sort a file with IP Addresses and another text column
by Anonymous Monk on Jun 14, 2001 at 21:08 UTC
    I'm not totally clear as to what you want to sort by. But the example below will sort on the first IP address of every line. If you want to sort by the country, it's even easier, modify as necessary (see by_country for an example).
    open(F, $ARGV[0]) or die "Couldn't open file\n"; print sort by_ip <F>; close(F); sub by_ip { my ($aip) = split /,/, $a; my ($bip) = split /,/, $b; my ($aa, $ab, $ac, $ad) = split /\./, $aip; my ($ba, $bb, $bc, $bd) = split /\./, $bip; return ($aa <=> $ba) || ($ab <=> $bb) || ($ac <=> $bc) || ($ad <=> $ +bd); } sub by_country { my ($ac) = (split /,/, $a)[2]; my ($bc) = (split /,/, $b)[2]; return ($ac cmp $bc); }

    Originally posted as a Categorized Answer.