//View Tip #275
Similar Tips
» Crawl a web page for links
» Random line
» List only the files that have been updated today.
» Counts files in the current directory and subdirectory
» Randomize lines in a file

 

Latest tips by RSS
Click here to subscribe
Follow Shell-Fu on Twitter
Click here to follow
Follow Shell-Fu on identi.ca
Click here to follow
This piece of code lists the size of every file and subdirectory of the current directory, much like du -sch ./* except the output is sorted by size, with larger files and directories at the end of the list. Useful to find where all that space goes.


du -sk ./* | sort -n | awk 'BEGIN{ pref[1]="K"; pref[2]="M"; pref[3]="G";} { total = total + $1; x = $1; y = 1; while( x > 1024 ) { x = (x + 1023)/1024; y++; } printf("%g%s\t%s\n",int(x*10)/10,pref[y],$2); } END { y = 1; while( total > 1024 ) { total = (total + 1023)/1024; y++; } printf("Total: %g%s\n",int(total*10)/10,pref[y]); }'


View Comments »




Comments 

Add your comment

Comments are currently disabled
hpt
why "x = (x + 1023)/1024", it should be "x = x / 1024" I think ...
Posted 2008-09-18 10:42:38
treadwm
How about

du -ks ./* | sort -n

instead?
Posted 2008-11-11 17:57:40
j0rn
even :

du -ksh ./* | sort -n

prints quite the same result
Posted 2009-02-18 17:23:14
spud
du -ksh ./* | sort -n gets close, but doesn't sort files of different size classes correctly, for example I get:
1.2M    ./Folder1
4.3G    ./Folder2
301M    ./Folder3
640K    ./Folder4
680K    ./Folder5

I made an attempt that doesn't use any math, but as a result you don't get the total size for the current directory, which I miss. (You could of course just run another du -sh, but that would take a lot longer than the posted script.  Anyway, here's my version for the fun of it, but I'll still stick with the OP.  Thanks, I love it!

alias dstat="du -sh ./* | sed -e 's/^\([0-9\.]*\)K/A \1/g' -e 's/^\([0-9\.]*\)M/B \1/g' -e 's/^\([0-9\.]*\)G/C \1/g' -e 's/^\([0-9\.]*\)T/D \1/g' | sort -k1.1,1.2d -k2n | sed -e 's/^A \([0-9\.]*\)/\1K/g' -e 's/^B \([0-9\.]*\)/\1M/g' -e 's/^C \([0-9\.]*\)/\1G/g' -e 's/^D \([0-9\.]*\)/\1T/g'"
Posted 2009-02-27 06:08:38
kap4lin
The '$2' in awk will not print the entire filenames. Also, the math there is not correct - doesnot match with individual du -sh values!

I like spud's solution which I modified to:

find . -maxdepth 1 -type d -print0 | xargs -0 du -sh | sed 's/^\([0-9\.]*\)\([KMGT]\)/\2 \1/;s/^G/N/' | sort -k1.1,1.2d -k2n | sed 's/^N/G/;s/^\([KMGT]\) \([0-9\.]*\) *\(.*\)/\2 \1 \3/' | awk '{printf("%5.1f %c  %s\n",$1,$2,gensub(/^[[:digit:]\. ]* [KMGT][ \t]*/,"",""))}'

You may remove '-type d' to get all files and dirs (but not recursing). Also, in spud's solution, no need to change K, M, and T; 'G' is the only odd ball!
Posted 2009-04-29 22:10:22
jaybeegee
The above complex solutions are ridiculous.

When using du you can specify more than one pattern match, so the simplest solution is

du -ks ./* ./.* | sort -n

which will show everything in kilobytes.

(use -ms for megabytes)
Posted 2009-05-24 18:50:27
jaybeegee
actually the above should be

du -kscx * .[^.]*  | sort -n
Posted 2009-05-28 11:19:07
gnu
Damn! I wrote this myself

$ type dusa
dusa is a function
dusa ()
{
   du -a --max-depth=1 | sort -n | awk '{
               sub("./","",$2);
               size=$1;
               $1="";
               unit="K";
               if (size >= 1024)
               {
                       size = size /1024;
                       unit="M";
               }
               if (size >= 1024)
               {
                       size = size /1024;
                       unit="G";
               }
               printf "%6.1f%s %s\n",  size, unit, $0;
       }'
}

A bit later I heard about the program ncdu (http://dev.yorhel.nl/ncdu). It's really cool.
Posted 2009-06-07 10:46:34
elvis
This only works with GNU Coreutils:

du -k --max-depth=1 | sort -rgb

The "--max-depth" flag saves a lot of unecessary scripting fluff compared to non-GNU versions.

Likewise, the "sort -rgb" is GNU-only.  "sort -rn" is the equivalent elsewhere.
Posted 2009-06-14 07:01:09
selivan
du ./* | sort -n | cut -f 2 | du -ch

Exactly the same, with K, M and G modifyers. Works with GNU coreutils
Posted 2011-05-26 07:21:39

Home Latest Browse Top 25 Random Hall Of Fame Contact Submit