SnapOverflow

SnapOverflow Logo SnapOverflow Logo

SnapOverflow Navigation

  • Home
  • Server
  • Ubuntu

Mobile menu

Close
  • Home
  • System Administrators
    • Hot Questions
    • New Questions
    • Tags
  • Ubuntu
    • Hot Questions
    • New Questions
    • Tags
  • Help
Home / server / Questions / 62411
Accepted
Tom Feiner
Tom Feiner
Asked: 2009-02-26 05:42:42 +0800 CST2009-02-26 05:42:42 +0800 CST 2009-02-26 05:42:42 +0800 CST

How can I sort du -h output by size

  • 772

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?

linux bash du gnu
  • 30 30 Answers
  • 1001294 Views

30 Answers

  • Voted
  1. Best Answer
    ptman
    2010-07-02T04:29:56+08:002010-07-02T04:29:56+08:00

    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)

    • 1893
  2. cadrian
    2009-02-26T05:52:03+08:002009-02-26T05:52:03+08:00
    du | sort -nr | cut -f2- | xargs du -hs
    
    • 105
  3. neutral
    2009-02-26T12:39:28+08:002009-02-26T12:39:28+08:00

    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.

    • 79
  4. Adam Bellaire
    2009-02-26T13:04:55+08:002009-02-26T13:04:55+08:00

    @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}'
    
    • 70
  5. chrisharris.
    2009-02-26T06:01:36+08:002009-02-26T06:01:36+08:00
    du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh
    
    • 47
  6. Douglas Leeder
    2009-02-26T05:53:52+08:002009-02-26T05:53:52+08:00

    As far as I can see you have three options:

    1. Alter du to sort before display.
    2. Alter sort to support human sizes for numerical sort.
    3. Post process the output from sort to change the basic output to human readable.

    You could also do du -k and live with sizes in KiB.

    For option 3 you could use the following script:

    #!/usr/bin/env python
    
    import sys
    import re
    
    sizeRe = re.compile(r"^(\d+)(.*)$")
    
    for line in sys.stdin.readlines():
        mo = sizeRe.match(line)
        if mo:
            size = int(mo.group(1))
            if size < 1024:
                size = str(size)+"K"
            elif size < 1024 ** 2:
                size = str(size/1024)+"M"
            else:
                size = str(size/(1024 ** 2))+"G"
    
            print "%s%s"%(size,mo.group(2))
        else:
            print line
    
    • 24
  7. Joachim Sauer
    2009-02-26T05:56:15+08:002009-02-26T05:56:15+08:00

    I've had that problem as well and I'm currently using a workaround:

    du -scBM | sort -n
    

    This will not produce scaled values, but always produce the size in megabytes. That's less then perfect, but for me it's better than nothing (or displaying the size in bytes).

    • 24
  8. Adam Bellaire
    2009-02-26T06:09:00+08:002009-02-26T06:09:00+08:00

    Found this posting elsewhere. Therefore, this shell script will do what you want without calling du on everything twice. It uses awk to convert the raw bytes to a human-readable format. Of course, the formatting is slightly different (everything is printed to one decimal place precision).

    #/bin/bash
    du -B1 | sort -nr  |awk '{sum=$1;
    hum[1024**3]="G";hum[1024**2]="M";hum[1024]="K";
    for (x=1024**3; x>=1024; x/=1024){
            if (sum>=x) { printf "%.1f%s\t\t",sum/x,hum[x];print $2;break
    }}}'
    

    Running this in my .vim directory yields:

    4.4M            .
    3.6M            ./colors
    372.0K          ./plugin
    128.0K          ./autoload
    100.0K          ./syntax
    100.0K          ./doc
    

    (I hope 3.6M of color schemes isn't excessive.)

    • 21
  9. slm
    2011-08-11T19:08:18+08:002011-08-11T19:08:18+08:00

    Here's an example that shows the directories in a more compact summarized form. It handles spaces in directory/filenames.

    % du -s * | sort -rn | cut -f2- | xargs -d "\n" du -sh
    
    53G  projects
    21G  Desktop
    7.2G VirtualBox VMs
    3.7G db
    3.3G SparkleShare
    2.2G Dropbox
    272M apps
    47M  incoming
    14M  bin
    5.7M rpmbuild
    68K  vimdir.tgz
    
    • 20
  10. Dennis Williamson
    2009-09-05T09:06:55+08:002009-09-05T09:06:55+08:00

    This version uses awk to create extra columns for sort keys. It only calls du once. The output should look exactly like du.

    I've split it into multiple lines, but it can be recombined into a one-liner.

    du -h |
      awk '{printf "%s %08.2f\t%s\n", 
        index("KMG", substr($1, length($1))),
        substr($1, 0, length($1)-1), $0}' |
      sort -r | cut -f2,3
    

    Explanation:

    • BEGIN - create a string to index to substitute 1, 2, 3 for K, M, G for grouping by units, if there's no unit (the size is less than 1K), then there's no match and a zero is returned (perfect!)
    • print the new fields - unit, value (to make the alpha-sort work properly it's zero-padded, fixed-length) and original line
    • index the last character of the size field
    • pull out the numeric portion of the size
    • sort the results, discard the extra columns

    Try it without the cut command to see what it's doing.

    Here's a version which does the sorting within the AWK script and doesn't need cut:

    du -h |
       awk '{idx = sprintf("%s %08.2f %s", 
             index("KMG", substr($1, length($1))),
             substr($1, 0, length($1)-1), $0);
             lines[idx] = $0}
        END {c = asorti(lines, sorted);
             for (i = c; i >= 1; i--)
               print lines[sorted[i]]}'
    
    • 20

Sidebar

Stats

  • Questions 681965
  • Answers 980273
  • Best Answers 280204
  • Users 287326
  • Popular
  • Answers
  • Marko Smith

    Ping a Specific Port

    • 18 Answers
  • Marko Smith

    What port does SFTP use?

    • 6 Answers
  • Marko Smith

    Resolve host name from IP address

    • 8 Answers
  • Marko Smith

    How can I sort du -h output by size

    • 30 Answers
  • Marko Smith

    Command line to list users in a Windows Active Directory group?

    • 9 Answers
  • Marko Smith

    What's the command-line utility in Windows to do a reverse DNS look-up?

    • 14 Answers
  • Marko Smith

    How to check if a port is blocked on a Windows machine?

    • 4 Answers
  • Marko Smith

    What port should I open to allow remote desktop?

    • 9 Answers
  • Marko Smith

    What is a Pem file and how does it differ from other OpenSSL Generated Key File Formats?

    • 3 Answers
  • Marko Smith

    How to determine if a bash variable is empty?

    • 15 Answers
  • Martin Hope
    Davie Ping a Specific Port 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    Deepak Mittal How to run a server on port 80 as a normal user on Linux? 2008-11-11 06:31:11 +0800 CST
  • Martin Hope
    MikeN In Nginx, how can I rewrite all http requests to https while maintaining sub-domain? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner How can I sort du -h output by size 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 What is the difference between double and single square brackets in bash? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch How do I change my private key passphrase? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt How does IPv4 Subnetting Work? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich What is a Pem file and how does it differ from other OpenSSL Generated Key File Formats? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent How to determine if a bash variable is empty? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus How do you find what process is holding a file open in Windows? 2009-05-01 16:47:16 +0800 CST

Related Questions

Trending Tags

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Home
  • Questions
    • Hot Questions
    • New Questions
  • Tags
  • Help

Footer

SnapOverflow

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Help

© 2022 SOF-TR. All Rights Reserve