in reply to Unsorted IP Addr list to sorted IP list with ranges
If there is a better solution that uses established modules, I would suggest that. Barring that, here is some code I was toying with a while back to do something similar-probably not the best or most efficient way to do it, however. (Address data was in __DATA__, which I did not include here for length.) Hope maybe this might give you an idea or two (if nothing else, maybe of how not to do it).
#!/usr/bin/perl -w use strict; my (%addresses); { # Load data into @addresslist, # ensuring only unique addresses are present my @addresslist = (); { my (%seen); while (<DATA>) { chomp; my $ip = unpack( "N", pack( "C4", split ( /\D+/, $_ ) ) ); $seen{ $ip }++; } @addresslist = keys(%seen); } # Look thru @addresslist, # storing in %addresses if there is not a key # where $flag <= $i <= $addresses{$flag}, or # incrementing $addresses{$flag} if $i == $addresses{$flag}+1 foreach my $i (@addresslist) { my $flag = 0; foreach my $k ( sort( keys(%addresses) ) ) { my $target = $addresses{$k} + 1; if ( $i == $target ) { $flag = $k; last; } } if ($flag) { $addresses{$flag}++; } else { $addresses{$i} = $i; } print "\n"; } # Join ranges that should have been connected, # but were not because data was not seen in sequence. my @startvalues = sort( keys(%addresses) ); my $i = shift (@startvalues); while (@startvalues) { my $k = shift (@startvalues); if ( $k == $addresses{$i} ) { $addresses{$i} = $addresses{$k}; delete( $addresses{$k} ); } else { $i = $k; } } } # Print address ranges on one line. foreach my $k ( sort( keys(%addresses) ) ) { print join ( '.', unpack( "C4", pack( "N", $k ) ) ); if ( $k != $addresses{$k} ) { print '-'; print join ( '.', unpack( "C4", pack( "N", $addresses{$k} ) ) ); } print " "; } print "\n";
|
|---|