[aklug] Re: perl lists question, sorting, sort of.

From: Michael Fowler <michael@shoebox.net>
Date: Tue Aug 17 2010 - 16:08:02 AKDT

On Tue, Aug 17, 2010 at 01:31:08PM -0800, Arthur Corliss wrote:
> perl -ane '$ip{$F[0]} .= join "", map { sprintf " %-10s", $_ }
> @F[1 .. $#F]; END { foreach (sort
> { sprintf( "%03d.%03d.%03d.%03d", split /\./sm, $a ) cmp
> sprintf( "%03d.%03d.%03d.%03d", split /\./sm, $b ) } keys %ip) {
> printf "%-15s%s\n", $_, $ip{$_} }; };' /etc/hosts
>
> This will columnize the hostnames (limiting each hostname to ten characters)
> and printing out the list sorted by IP in numerical order by each octet.

inet_aton($a) cmp inet_aton($b) would be a simpler means of
accomplishing the sort, though both are going to choke on IPv6
addresses. What do you have against IPv6, Arthur?

Comments and blank lines will also throw it a bit.

Also, /sm? You have joined the cargo cult!

Columnated output, ordered by IPv4 address, followed by IPv6 addresses,
with comments removed. IPv6 sorting could be improved with the addition
of the Socket6 module, but that isn't core.

It could be improved by reordering each cell by length, that way the
columns are approximately equal in size.

perl -MSocket=inet_aton -anwe '
    BEGIN { $maxcol = 0 }

    push @{ $ip{$F[0]} }, @F[1..$#F] unless /^\s*(#|$)/;
    $maxcol = @F if @F > $maxcol;

    END {
        @table = map { [$_, @{ $ip{$_} }] } keys %ip; # generate table
        foreach my $row (@table) {
            push @$row, ("") x ($maxcol - @$row); # pad the row
            foreach my $i (0 .. $#$row) {
                $maxlen[$i] = length $row->[$i]
                    if not defined $maxlen[$i] or length $row->[$i] > $maxlen[$i];
            }
        }

        $format = join(" ", map { "%-" . $_ . "s" } @maxlen) . "\n";
        printf $format, @$_ for sort {
            my $ai = inet_aton($a->[0]);
            my $bi = inet_aton($b->[0]);
            return -1 if defined $ai and not defined $bi;
            return 1 if not defined $ai and defined $bi;
            return $a->[0] cmp $b->[0] if not defined $ai and not defined $bi;
            return $ai cmp $bi;
        } @table;
    }
' /etc/hosts

--
Michael Fowler
www.shoebox.net
---------
To unsubscribe, send email to <aklug-request@aklug.org>
with 'unsubscribe' in the message body.
Received on Tue Aug 17 16:10:00 2010

This archive was generated by hypermail 2.1.8 : Tue Aug 17 2010 - 16:10:00 AKDT