#!/bin/sh #\- sort by size a "du" listing; filter only #usage: %dusort [-t] #typically: du | dusort [-t] #sort a "du" listing by directory size and format #option: -t => output format = dir(size) default => size dir # #BUG: if two or more directories with same path have same size, then #their subdirectories will be sorted together and printed as a block #after the directories are printed as a block. # #by conor rafferty, stanford #(X-Archive: comp.sources.misc/8709/10) #slightly modified by ja rupley, tucson, arizona FILES= TFORM=0 while test $# -ge 1; do case $1 in -t) TFORM=1; ;; *) FILES="$FILES $1"; ;; esac shift done #build complex keys so that subdirectories move with parent awk '{ size[ $2] = $1 } END { for (i in size) { printf "%s ", i; oj = 1; l = length(i); #build up an aggregate key from all its parents for (j = 1; j <= l; ) { for (; j <= l; j++) if (substr(i,j,1) == "/") break; name = substr(i, oj, j-oj); j++; printf "%d ", size[name]; } #print itself once more to compare ahead of its children printf "%d\n", size[i]; } }' $FILES | #sort numerically sort -r -n +1 -2 +2 -3 +3 -4 +4 -5 +5 -6 +6 -7 +7 -8 +8 -9| #just print the path and its size. In two popular flavors. awk '{if('$TFORM') printf "%s(%d)\n", $1, $NF; else printf "%8d\t%s\n", $NF, $1}' | #indent directories # This awk could be combined with the previous one # but it really performs a separate function. # Cut it off and put it in a separate file called 'ind' if you like it. # # ind: indent output from du or find # awk ' BEGIN {blank=" "} { for (s=length; s > 0 && substr($0, s, 1) > " " ; s--) ; for (e=length; substr($0, e, 1) != "/" && e > s+1; e--) ; print substr($0, 1, s) substr(blank, 1, e-s-1) substr($0, e); } '