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


in reply to Re: du -h, sorted
in thread du -h, sorted

Are you sure yours gets correct results? I'm getting 372K between 4.4M and 3.6M.
perl -e 'sub c{pop=~/[GMK]/;ord($&)&7}print sort{c($b)<=>c($a)or$b<=>$ +a}`du -h`'

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^3: du -h, sorted
by grinder (Bishop) on Feb 26, 2009 at 00:17 UTC

    You're absolutely correct. Allow me to replace it by the following, clocking in at 87.

    perl -e'sub h{pop=~/(...)(.)/&&{M,1e3,G,1e6}->{$2}+$1}print sort{h($b) +<=>h$a}`du -h`'

    update: No wait! There's something in your idea of bitanding... Just have to get rid of the second spaceship comparator...

    perl -e'sub c{pop=~/[GMK]/;(ord$&&7).1e3+$`}print sort{c($b)<=>c$a}`du + -h`'

    76 strokes.

    • another intruder with the mooring in the heart of the Perl

      Alas, your last two methods put a 400K file before a 399M file... For the first one, I added a "K" key to your anonymous hash:

      perl -e 'sub h{pop=~/^([\d.]+)(.)/&&{K,1e1,M,1e3,G,1e6}->{$2}+$1}print + sort{h($b)<=>h$a}`du -h`'

      For the second one, I think you're in a bind because ord(k)&7 and ord(K)&7 are equal...

      And I offer another method, bumming heavily from yours, longer but possibly faster on large filesystems:

      perl -e 'print map substr($_,8),reverse sort map sprintf("%8d",(/^([\d +.]+)([kKMG])/)?{K,1e1,M,1e3,G,1e6}->{$2}+$1:$1).$_,`du -h`'
      Oh, I see. Could I then also change the regex to save two more characters?
      perl -e'sub c{pop=~/.\s/;(ord$&&7).1e3+$`}print sort{c($b)<=>c$a}`du - +h`'
      74 characters.

      And, in fact, since we are only using .1e3 to make sure the sizes sort properly, why not save one more:
      perl -e'sub c{pop=~/.\s/;(ord$&&7)**7+$`}print sort{c($b)<=>c$a}`du -h +`'
      73 characters.

        Slick! But how about 70, using 'x' instead of '**', and 'die' instead of 'print':

        perl -e'sub c{pop=~/.\s/;(ord$&&7)x7+$`}die sort{c($b)<=>c$a}`du -h`'