This question already has an answer here:

I have a directory with the following subdirectories, i.e. If I run $ tree -L 1

├── 2007-06-20_to_2008-10-01
├── 2008-07-21_to_2008_08_12-Nokia 2mp
├── 2009-11-01_to_2011-01-10 - All iphone Pics
├── 2011-01-01 palliser-pics
├── 2011-03-10_to_2011-04-12-few iphone pics b4 switch to HTC
└── 2011-03-31-to-2013-05-01 ALL HTC pics-backup-prior-to-factory-reset

I would like to see the amount of diskspace those 2 directories and all their contents take up.
e.g. desired output, something like

2.7G  2007-06-20_to_2008-10-01
200MB 2008-07-21_to_2008_08_12-Nokia 2mp
1.3G  2009-11-01_to_2011-01-10 - All iphone Pics
667MB 2011-01-01 palliser-pics
2.3G  2011-03-10_to_2011-04-12-few iphone pics b4 switch to HTC
123MB 2011-03-31-to-2013-05-01 ALL HTC pics-backup-prior-to-factory-reset

So I have been trying:

find .  -maxdepth 1 -type d | xargs du -h 

but because some of the directory names contain spaces each line from the find output is producing many WORD's before being passed to xargs, is it possible to fix this?

I know the root cause of the problem is caused by the spaces in the files, and I will use rename to fix if I cant find a way to get disksize with du, find and xargs

marked as duplicate by Gilles 'SO- stop being evil', cuonglm, garethTheRed, cas, Bananguin Nov 16 '15 at 13:20

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    find . ! -name . -prune -type d -exec du -h {} + – mikeserv Nov 15 '15 at 6:06
  • thanks its an improvement, but that command is listing out all the subdirectories - and then seems to be looping back and re-producing that output another 4 or 5 times – the_velour_fog Nov 15 '15 at 6:13
  • ah you edited your comment. using {} + seemed to fix the looping issue - but its still printing the subdir's? – the_velour_fog Nov 15 '15 at 6:15
  • yeah, du does its own path traversal. user du -sh to summarize each argument. – mikeserv Nov 15 '15 at 6:19
  • then that summarises too much - it only du once producing one line of output containing the grand total for all directories. I guess -exec is the only option - but its obviously tricky to predict what arguments its going to use – the_velour_fog Nov 15 '15 at 6:24

find | xargs should always be used in conjunction with -print0 and -0, as explained in man find:

          True; print the full file name on the standard output, followed
          by a null character (instead of the newline character that
          -print uses).  This allows file names that contain newlines or
          other types of white space to be correctly interpreted by
          programs that process the find output.  This option corresponds
          to the -0 option of xargs.

Thus you want:
find . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 du -sh
or without find and with a sufficiently evolved shell (zsh):
print -N *(/) | xargs -0 du -sh
leading you to the even simpler:
du -sh *(/)

  • Nice one , thanks. I had seen the print0 previously but didn't know what it was used for. – the_velour_fog Nov 15 '15 at 7:14
  • @kos: Is not; the root . is at depth 0, and we want to get rid of it. That's what other commentators did with ! -name . -prune. – Michaël Nov 15 '15 at 8:26
  • My bad, sorry, I missed that point. – kos Nov 15 '15 at 8:28
  • Although this is arguably not a nice behavior from du that du -s a a/b only prints the value for a. I'll report that. – Michaël Nov 15 '15 at 8:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.