How can I sort du -h output by size

981,315

Solution 1

As of GNU coreutils 7.5 released in August 2009, sort allows a -h parameter, which allows numeric suffixes of the kind produced by du -h:

du -hs * | sort -h

If you are using a sort that does not support -h, you can install GNU Coreutils. E.g. on an older Mac OS X:

brew install coreutils
du -hs * | gsort -h

From sort manual:

-h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)

Solution 2

du | sort -nr | cut -f2- | xargs du -hs

Solution 3

There is an immensely useful tool I use called ncdu that is designed for finding those pesky high disk-usage folders and files, and removing them. It's console based, fast and light, and has packages on all the major distributions.

Solution 4

@Douglas Leeder, one more answer: Sort the human-readable output from du -h using another tool. Like Perl!

du -h | perl -e 'sub h{%h=(K=>10,M=>20,G=>30);($n,$u)=shift=~/([0-9.]+)(\D)/;
return $n*2**$h{$u}}print sort{h($b)<=>h($a)}<>;'

Split onto two lines to fit the display. You can use it this way or make it a one-liner, it'll work either way.

Output:

4.5M    .
3.7M    ./colors
372K    ./plugin
128K    ./autoload
100K    ./doc
100K    ./syntax

EDIT: After a few rounds of golf over at PerlMonks, the final result is the following:

perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;die@h{sort%h}'

Solution 5

du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh
Share:
981,315

Related videos on Youtube

Tom Feiner
Author by

Tom Feiner

Updated on September 17, 2022

Comments

  • Tom Feiner
    Tom Feiner over 1 year

    I need to get a list of human readable du output.

    However, du does not have a "sort by size" option, and piping to sort doesn't work with the human readable flag.

    For example, running:

    du | sort -n -r 
    

    Outputs a sorted disk usage by size (descending):

    du |sort -n -r
    65108   .
    61508   ./dir3
    2056    ./dir4
    1032    ./dir1
    508     ./dir2
    

    However, running it with the human readable flag, does not sort properly:

    du -h | sort -n -r
    
    508K    ./dir2
    64M     .
    61M     ./dir3
    2.1M    ./dir4
    1.1M    ./dir1
    

    Does anyone know of a way to sort du -h by size?

  • Douglas Leeder
    Douglas Leeder about 15 years
    And it'll do a huge amount of duplicate counting.
  • Tom Feiner
    Tom Feiner about 15 years
    I like th -BM switch, which is basically the same as -m, but it has the advantage of displaying the size and M postfixed to it, so you get 10M which is much clearer than just 10 :)
  • macb
    macb about 15 years
    that's what xargs does ;-)
  • hasen
    hasen about 15 years
    it would help if you explain why that works??
  • Douglas Leeder
    Douglas Leeder about 15 years
    First it does the normal du - then for each entry it recalculates the size just to print it in human readable form.
  • Antonio Diaz
    Antonio Diaz about 15 years
    I have a Perl answer, too, but I think it might make people hate me: du -B1 | sort -nr | perl -e '%h=(0=>b,1=>K,2=>M,3=>G);for(<>){($s,@f)=split/\s+/;$e=3;$e‌​-- while(1024**$e>$s);$v=($s/(1024**$e));printf "%-8s%s\n",sprintf($v >= 100 ? "%d%s" : "%.1f%s",$s/(1024**$e),$h{$e}),@f;}'
  • Antonio Diaz
    Antonio Diaz about 15 years
    Even though the Perl answer actually gives its formatting much closer to du. Although the rounding is off... It looks like du always gives ceil() rather than round()
  • macb
    macb about 15 years
    @Douglas Leeder: you are right for the duplicate counting, but think that the second du does not start from cold cache (thanks to the OS) @hasen j: xargs is a very useful command, it splits its stdin and feeds it as arguments to the given command
  • Admin
    Admin about 15 years
    hehe, I always forget about xargs. ;) At the end of the day, whatever gets the job done imo.
  • Antonio Diaz
    Antonio Diaz about 15 years
    Hey, why did I use a hash there? Should've been an array... morning-brain grumble....
  • Admin
    Admin about 15 years
    That doesn't give the human-readable output, though, which is what the OP was looking for.
  • Admin
    Admin about 15 years
    Don't really care about reputation score, but I am a bit confused as to why this answer has 12 votes when my more or less identical answer below has none.
  • Antonio Diaz
    Antonio Diaz about 15 years
    Added a better Perl solution as another answer.
  • hipe
    hipe about 15 years
    Chris's is actually superior since it works with paths containing whitespace. Throwing a vote your way, buddy.
  • Joachim Sauer
    Joachim Sauer about 15 years
    +1 for one of the rare, valid exceptions to "do one thing and do it right". Unless someone gets sort to understand the SI-prefix and/or the binary prefixes.
  • ojblass
    ojblass almost 15 years
    Very nice... I wondier if the results could be fed to standard out... I am so lazy that I cannot read the manual
  • Alberto
    Alberto over 14 years
    Two reasons: most folks just vote for the first good answer they see, and secondly, many people don't know what the -k option to du does.
  • Dennis Williamson
    Dennis Williamson over 14 years
    Your short version outputs on stderr because of the die can you change it to make it output on stdout?
  • Antonio Diaz
    Antonio Diaz over 14 years
    Change the die to a print and it will go to stdout. It's just two more characters.
  • Bill Weiss
    Bill Weiss about 14 years
    At least here, that doesn't work. houdini@clanspum:~/ > ls -1Ssh | grep clanspum 4.0K drwxr-xr-x 27 houdini users 4.0K 2010-02-15 12:35 clanspum/ 0 drwxr-xr-x 2 houdini users 77 2010-02-15 13:06 clanspum-s/ houdini@clanspum:~/ > du -sh clanspum/ 602M clanspum/
  • Bill Weiss
    Bill Weiss about 14 years
    ... pretend that was formatted correctly. Point is, it shows a directory as being "4.0K", while du -sh shows "602M". The latter is correct.
  • user2910702
    user2910702 almost 14 years
    And as ptman mentions below: ta da! (new sort flag)
  • user2910702
    user2910702 almost 14 years
    gt5 is in the same vein; its killer feature is displaying growth.
  • Vi.
    Vi. over 13 years
    Both versions fail when filenames contain spaces
  • wodow
    wodow about 13 years
    The relevant section of the manual: gnu.org/software/coreutils/manual/…
  • Richard Poirier
    Richard Poirier about 13 years
    Easy to install on OS X with homebrew -- brew install coreutils.
  • anthony
    anthony about 13 years
    thank you! this is the first example that works for me in OS X 10.6 not counting the perl/phython-scripts. and thanks again for the good explanation. always nice to learn something new. awk sure is a powerful tool.
  • voretaq7
    voretaq7 over 12 years
    Ugly, but cross-platform :).
  • voretaq7
    voretaq7 over 12 years
    Great utility, but not installed by default on any OS I'm aware of. Not necessarily a problem, but one more program to have to look after...
  • ThorstenS
    ThorstenS over 12 years
    wow, thanks. Much better thank my evergreen du -sk * | sort -n
  • JacketSnatcher
    JacketSnatcher about 12 years
    works on ubuntu!
  • chutz
    chutz almost 12 years
    Good one! I personally always did du -BM | sort -nr as a workaround - it is human readable enough, and it is sorted, if anyone is stuck with older coreutils.
  • nandoP
    nandoP over 10 years
    impressive perl hackistry
  • Brian Cline
    Brian Cline over 10 years
    If using on OSX via Homebrew, note that you'll now need to use gsort rather than sort: du -hs * | gsort -h
  • Paul Draper
    Paul Draper over 10 years
    @chutz, that puts 168K before 104M.
  • chutz
    chutz over 10 years
    @PaulDraper, du -BM prints everything in megabytes, so a file that is 168K would actually display as 0M. Unless there is some other version discrepancy I am not aware of. My version of du only shows integer megabyte values.
  • Paul Draper
    Paul Draper over 10 years
    @chutz, yes. du -sBM * | sort -nr does work.
  • RSFalcon7
    RSFalcon7 about 10 years
    The result is in reverse order :(
  • laggingreflex
    laggingreflex over 9 years
  • laggingreflex
    laggingreflex over 9 years
    Can't use with du -k --total, gives error at the end du: cannot access 'total': No such file or directory
  • laggingreflex
    laggingreflex over 9 years
    Perfect. @RSFalcon7 To un-reverse order just change it to sort{h($a)<=>h($b)} or make it reverse sort{..
  • zegkljan
    zegkljan about 9 years
    i think if it is a very big number, then the unit is gone and the number displayed is small... try 23423423432423
  • shaheen
    shaheen almost 9 years
    If using on FreeBSD, try gsort instead sort.
  • BurninLeo
    BurninLeo over 8 years
    That's really cool! And much faster than hanging around with du, if you just want to identify the large directories.
  • mwfearnley
    mwfearnley over 8 years
    The way sort -h seems to work is to sort by the suffix first, and then by the numeric value. e.g. 2000 is deemed to be less than 1K. This would be fine in most autogenerated listings though, where a smaller number will never have a larger suffix then a larger number.
  • Paul Gear
    Paul Gear over 8 years
    That's not a great solution, because it traverses the file system twice.
  • Jeff Olson
    Jeff Olson over 8 years
    This is the simplest solution I've seen so far on this page, thank you!
  • Mau
    Mau over 8 years
    i like this one more any other answer. how would you go to show only the first 50 results?
  • HankCa
    HankCa over 8 years
    MacOSX by default (i.e. outside of home-brew) doesn't support a proper xargs so this form was necessary. However for files with spaces in them you need to set IFS: IFS=$'\n'
  • pojo
    pojo over 7 years
    Standard du on OS X does not support the suggested options, but the one from coreutils does (gdu) gdu -hs * | gsort -h
  • HankCa
    HankCa over 7 years
    Great thanks for that. I changed the du to du -sh * to show just the immediate files and directories without recursive descent.
  • Adam Katz
    Adam Katz about 7 years
    The BSD du -d 1 syntax has been supported by GNU du since coreutils 8.6 was released in 2010 (though its first Red Hat availability was RHEL 7 in 2014), so you no longer need --maxdepth=1. I only found out about this recently myself.
  • jasonology
    jasonology almost 7 years
    Just tried this on macOS Sierra. Works as expected. Nice!
  • Samuel Lelièvre
    Samuel Lelièvre about 6 years
    @Mauro -- just pipe the result to head by adding ` | head -50` at the end.
  • Mike Turley
    Mike Turley about 6 years
    For future Google users like myself, if you want to use this answer's command but sort by size descending instead of ascending, you just need the -r option for size. To scroll a list of the largest stuff, use du -hs * | sort -hr | less.
  • giorgio79
    giorgio79 almost 6 years
    This solution does not work on hidden directories that start with a "." like ".git"
  • ptman
    ptman almost 6 years
    @giorgio79 in that case, use * .??*
  • vladkras
    vladkras almost 6 years
    I use du -sh ./* | sort -g cause -h is not supported on BusyBox v1.27.2
  • Tripp Kinetics
    Tripp Kinetics over 5 years
    Loosely based on this one-liner, I created a script for providing a human-readable, sorted du(1) output. Please refer to my answer, serverfault.com/a/937459/218692.
  • Selwyn Polit
    Selwyn Polit over 5 years
    I like to show the top ten sorted largest to smallest with du -sh * | sort -h -r | head -n 10
  • Marco Marsala
    Marco Marsala about 5 years
    Simpler: du -h | sort -h
  • mjs
    mjs almost 5 years
    This is the best, but does not account for bytes (with G,M, K) . Otherwise, nearly perfect!
  • neverMind9
    neverMind9 almost 5 years
    For me, sort itself already has that feature. gsort is not pre-installed.
  • baptx
    baptx almost 4 years
    What is the best practice between du -hs * and du -h -d1?
  • ptman
    ptman almost 4 years
    @baptx They're different things. Do you want dotfiles or not?
  • baptx
    baptx almost 4 years
    @ptman thanks, indeed I want to see everything, including files and folders starting with a dot but du -hs * did not display them. In this case, you should add to your answer that we have to use du -h -d1.
  • adfaklsdjf
    adfaklsdjf over 3 years
    Struggling with getting this into a bash alias or function.. it doesn't seem to like the 3 backticks...
  • John Hamilton
    John Hamilton over 3 years
    Holy hell, that PerlMonks page seems like they're talking in some ancient language...
  • David Okwii
    David Okwii about 3 years
    Add the -r option to sort in descending order as in " du -sh * | sort -hr"
  • cregox
    cregox almost 3 years
    highly recommend using du -chxd 1 rather than summary. it's much more informative! 😁
  • yankeemike
    yankeemike over 2 years
    If I'm in a directory and I want to list the files in reverse size order I do du -h | sort -rh