How to get the summarized sizes of directories and their subdirectories?

316

131

Let's say I want to get the size of each directory of a Linux file system. When I use ls -la I don't really get the summarized size of the folders.

If I use df I get the size of each mounted file system but that also doesn't help me. And with du I get the size of each subdirectory and the summary of the whole file system.

But I want to have only the summarized size of each directory within the ROOT folder of the file system. Is there any command to achieve that?

2ndkauboy

Posted 2010-07-11T17:26:29.107

Reputation: 3 323

The --total flag was helpful for me. E.g. du -sh --total applications/*. https://askubuntu.com/a/465436/48214

– Ryan – 2018-07-07T15:29:20.647

Answers

450

This does what you're looking for:

du -sh /*

What this means:

  • -s to give only the total for each command line argument.
  • -h for human-readable suffixes like M for megabytes and G for gigabytes (optional).
  • /* simply expands to all directories (and files) in /.

    Note: dotfiles are not included; run shopt -s dotglob to include those too.

Also useful is sorting by size:

du -sh /* | sort -h

Here:

  • -h ensures that sort interprets the human-readable suffixes correctly.

Thomas

Posted 2010-07-11T17:26:29.107

Reputation: 4 979

4@psur or you can use ./*/ to get only subfolders and not all items – relascope – 2016-01-28T23:48:37.557

9If you have dot-directories in the root directory, you can use shopt -s dotglob to include them in the count. – Philipp – 2010-07-11T21:55:57.180

9Sorted version: du -sh /* | sort -h – Vu Anh – 2017-07-28T03:24:02.417

Nice tip on the sort -h – SDsolar – 2018-03-04T17:14:33.137

If you're using alpine, -h isn't an available flag on sort. sort -nr should get you the same result, leading to du -sh /* | sort -nr. – c1phr – 2018-08-20T11:23:46.277

3@c1phr If your sort doesn't have -h, you need to leave it off from du as well, otherwise the sorting will mix up kilo/mega/gigabytes. du -s /* | sort -nr. – Thomas – 2018-08-20T12:30:18.867

1This should throw the top ten of biggest directories: du -hS /var/lib/docker | sort -rh | head -10 – joseluisq – 2019-01-30T07:48:20.983

I've ended with du -hs /* | sort -hr. It outputs sizes in readable format (5GB, 6.6M) and sorts values descending. – userlond – 2019-07-08T08:21:57.173

10It's very usefull, because it's simple and you can place what path you want instead of /*, e.g. ./ for current directory or ./* for each item in current directory. – psur – 2012-08-09T06:22:40.270

84

I often need to find the biggest directories, so to get a sorted list containing the 20 biggest dirs I do this:

du -m /some/path | sort -nr | head -n 20

In this case the sizes will be reported in megabytes.

Janne Pikkarainen

Posted 2010-07-11T17:26:29.107

Reputation: 6 717

1Works in Ubuntu 16.04. Nice tip. – SDsolar – 2018-03-04T17:15:44.093

1sudo du -haxt 1G / | sort -hr | head -30 – deviant – 2018-10-05T10:03:45.340

12Here's a way to get it more readable du -sh /some/path | sort -hr | head -n 20 – Xedecimal – 2013-07-08T15:49:08.467

7@Xedecima the problem with using h is the sort doesn't know how to handle different sizes. For example 268K is sorted higher than 255M, and both are sorted higher than 2.7G – chrisan – 2013-12-27T18:33:41.947

5The -h (human readable) argument on the 'sort' command should properly read these values. Just like du's -h flag exports them. Depending on what you're running I'm guessing. – Xedecimal – 2014-04-14T18:02:46.657

24

I like to use Ncdu for that, you can use the cursor to navigate and drill down through the directory structure it works really well.

BuddhaLincoln

Posted 2010-07-11T17:26:29.107

Reputation: 341

1Awesome. Keywords: du meets ncurses. You can use b to drop into a shell in the directory. – Ciro Santilli 新疆改造中心法轮功六四事件 – 2019-01-31T15:28:39.597

12

The existing answers are very helpful, maybe some beginner (like me) will find this helpful as well.

  1. Very basic loop, but for me this was a good start for some other size related operations:

    for each in $(ls) ; do du -hs "$each" ; done
    
  2. Very similar to the first answer and nearly the same result as 1.), but it took me some time to understand the difference of * to ./* if in a subdirectory:

    du -sh ./*
    

Martin

Posted 2010-07-11T17:26:29.107

Reputation: 225

for each does not work as it appends console characters (eg \033[) to the list of folders – machineaddict – 2019-02-06T11:57:12.637

@machineaddict not sure what you mean. I use this all the time, works for me just fine. – Martin – 2019-02-06T12:57:58.630

try to run your command starting with for each. it will not work – machineaddict – 2019-02-06T14:34:23.830

i run the command exactly as written here. starting with for each. works. – Martin – 2019-02-07T14:29:53.943

9

The following du invocation should work on BSD systems:

du -d 1 /

Philipp

Posted 2010-07-11T17:26:29.107

Reputation: 261

1in other systems, its --max-depth – Vishnu Kumar – 2015-09-01T12:49:23.560

2My du (Ubuntu 10.4) doesn't have a -d option. What system are you on? – Thomas – 2010-07-11T17:30:11.843

1On my openSUSE it doesn't have a -d option either :( – 2ndkauboy – 2010-07-11T17:33:58.233

1OK, then it's a BSD option only (I'm on OS X). – Philipp – 2010-07-11T17:37:10.813

1Right portable option combination on BSD/NIX is `du -sk /. I hate the-kstuff soooo much. Linux'-h` totally rocks. – Dummy00001 – 2010-07-11T19:46:35.657

5

This isn't easy. The du command either shows files and folders (default) or just the sizes of all items which you specify on the command line (option -s).

To get the largest items (files and folders), sorted, with human readable sizes on Linux:

du -h | sort -h

This will bury you in a ton of small files. You can get rid of them with --threshold (1 MB in my example):

du --threshold=1M -h | sort -h

The advantage of this command is that it includes hidden dot folders (folders which start with .).

If you really just want the folders, you need to use find but this can be very, very slow since du will have to scan many folders several times:

find . -type d -print0 | sort -z | xargs --null -I '{}' du -sh '{}' | sort -h

Aaron Digulla

Posted 2010-07-11T17:26:29.107

Reputation: 6 035

2--threshold ^^^ this option is not availavle on linux – podarok – 2015-10-06T12:30:36.950

2@podarok It's available on OpenSUSE 13.2 Linux. Try to find a more recent version of your distribution or compile a more recent version of the package yourself. – Aaron Digulla – 2015-10-07T08:51:02.923

1It doen't work on Ubuntu LTS (14.04). It is the most recent one )) – podarok – 2015-10-07T13:16:22.160

1@podarok Which version of GNU coreutils? Mine is 8.24. – Aaron Digulla – 2015-10-08T07:33:24.203

Sorry. It was not on Ubuntu 14.04. It was Centos 6.6. Lost in consoles.... – podarok – 2015-10-08T09:49:01.057

Yes, that can be very slow. But you can cache the output from a single find and work from that. No need to access the filesystem several times. – Hennes – 2015-12-24T10:23:43.723

@Hennes: How do you cache file sizes in a shell script? – Aaron Digulla – 2016-01-12T14:03:51.157

2

Caching might have been a bad term. I was thinking of something like done in this port http://superuser.com/a/597173/121352 where we scan the disks contents once into a mapping and then continue using data from that mapping rather than hitting the disk again.

– Hennes – 2016-01-12T14:09:27.413

2

Be aware, that you can't compare directories with du on different systems/machines without getting sure, both share the same blocksize of the filesystem. This might count if you rsync some files from a linux machine to a nas and you want to compare the synced directory on your own. You might get different results with du because of different blocksizes....

Jimmy Koerting

Posted 2010-07-11T17:26:29.107

Reputation: 191

1

You could use ls in conjunction with awk:

ls -al * | awk 'BEGIN {tot=0;} {tot = tot + $5;} END {printf ("%.2fMb\n",tot/1024/1024);}'

The output of ls is piped to awk. awk starts processing the data. Standard delimiter is space. The sum variable tot is initialised to zero; the following statement is executed for each row/line outputted by ls. It merely increments tot with the size. $5 stands for fifth column (outputted by ls). At the end we divide by (1024*1024) to sum in megabytes.

If you would convert this into a script or function (.bashrc) you can also use it to get the size of certain subsets of directories, according to filetypes.

If you want system wide information, kdirstat may came in handy!

J.M. Stoorvogel

Posted 2010-07-11T17:26:29.107

Reputation: 11

1

I agree one can expand this example and do tricks like getting the size of "certain subsets of directories, according to filetypes" etc.; it may seem a good starting point. Nevertheless this solution is flawed from the start. To every user who would like to use this method I recommend reading answers and comments to this question as well as the article linked there. I don't say you cannot do it at all. Know the limitations, that's all.

– Kamil Maciorowski – 2016-12-22T18:42:28.280

1

You might also want to check out xdiskusage. Will give you the same information, but shown graphically, plus allows to drill down (very useful). There are other similar utilities for KDE and even Windows.

sleske

Posted 2010-07-11T17:26:29.107

Reputation: 19 887