#!/usr/bin/perl -w ###################################################################### # sort-hr April 2006 # Horms horms@verge.net.au # # sort-hr # Sort human readable output of du -h, ls -h, etc... # Copyright (C) 2006 Horms # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA # ###################################################################### # TODO: Support sort(1)'s command line options { my @out; while (<>) { if (m/(\S+)\s+(.+)/) { push @out, [ $1, $2 ]; } else { chomp; push @out, [ $_ ]; } } for my $i (sort { sort_f($a, $b) } @out) { if (defined @$i[1]) { printf "%-7s %s\n", @$i[0], @$i[1]; } else { print @$i[0] . "\n"; } } } sub sort_f { my ($a, $b) = (@_); my $a_head; my $a_unit; my $b_head; my $b_unit; if (@$a[0] eq @$b[0]) { return 0; } ($a_head, $a_unit) = hr_expand(@$a[0]); ($b_head, $b_unit) = hr_expand(@$b[0]); if (defined ($a_head) and defined ($b_head) ) { if ($a_unit != $b_unit) { return $a_unit <=> $b_unit; } return $a_head <=> $b_head; } if (not defined ($a_head) and not defined ($b_head) ) { return @$a[0] cmp @$b[0]; } elsif (not defined ($a_head) ) { return 1; } elsif (not defined ($b_head) ) { return -1; } die; } sub hr_expand { my ($x) = (@_); my $head; my $unit; $x =~ m/^([0-9]+(\.[0-9]+)?)([kmgtp])?$/i or return; unless (defined($3)) { return($1, 1); } $head = $1; $unit = lc($3); $unit =~ tr/kmgtp/23456/; return ($head, $unit); } 0;