Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Assume there's an image storage directory, say, ./photos/john_doe, within which there are multiple subdirectories, where many certain files reside (say, *.jpg). How can I calculate a summary size of those files below the john_doe branch?

I tried du -hs ./photos/john_doe/*/*.jpg, but this shows individual files only. Also, this tracks only the first nest level of the john_doe directory, like john_doe/june/, but skips john_doe/june/outrageous/.

So, how could I traverse the entire branch, summing up the size of the certain files?

share|improve this question

5 Answers 5

up vote 32 down vote accepted
find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$

If more than one invocation of du is required because the file list is very long, multiple totals will be reported and need to be summed.

share|improve this answer
Thank Gilles for shortening the answer – SHW Jun 26 '12 at 6:34
That assumes the list of files is short enough than only one invocation of du is run. – Stéphane Chazelas Aug 5 '14 at 9:35
find -iname 'file*' -exec du -cb {} + | grep total$ | cut -f1 | paste -sd+ - | bc # summed byte size – Michal Čizmazia Jul 15 at 13:55
If your system works under other language then you need to change total$ to other word like razem$ in Polish. – Zbyszek Jul 26 at 12:49
du -ch public_html/images/*.jpg | grep total
20M total

gives me the total usage of my .jpg files in this directory.

To deal with multiple directories you'd probably have to combine this with find somehow.

You might find du command examples useful (it also includes find)

share|improve this answer
This doesn't traverse the underlying directories? – mbaitoff Jun 26 '12 at 5:48
super simple - not sure about recursive directories, but for a single directory, easy and obvious, should have thought of this! – Willshaw Media Jan 14 at 9:51

Primarily, you need two things:

  • the -c option to du, to tell it to produce a grand total;
  • either find or ** to traverse subdirectories.
du -ch -- **/*.jpg | tail -n 1
share|improve this answer

The answers given until now do not take into account that the file list passed from find to du may be so long that find automatically splits the list into chunks, resulting in multiple occurences of total.

You can either grep total (locale!) and sum up manually, or use a different command. AFAIK there are only two ways to get a grand total (in kilobytes) of all files found by find:
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'

find . -type f -iname '*.jpg' -print0: Find all files with the extension jpg regardless of case (i.e. *.jpg, *.JPG, *.Jpg...) and output them (null-terminated).
xargs -r0 du -a: -r: Xargs would call the command even with no arguments passed, which -r prevents. -0 means null-terminated strings (not newline terminated).
awk '{sum+=$1} END {print sum}': Sum up the file sizes output by the previous command

And for reference, the other way would be
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-

share|improve this answer
Additional hint: On my HDD with 23428 files (22323 being images) the first method runs 1 sec while the second one runs 3.8 secs. – Jan Aug 5 '14 at 10:12
Note that both assume a GNU system. The first one assumes file names don't contain newline characters. – Stéphane Chazelas Aug 6 '14 at 13:06
I'd bet the du --file0-from took longer because you ran it first (caching effect). – Stéphane Chazelas Aug 6 '14 at 13:07
With xargs, several du -a may be run, so you may have discrepancies if there are hard links. – Stéphane Chazelas Aug 6 '14 at 13:09

If the list of files is too big that it can't be passed to a single invocation of du -c, on a GNU system, you can do:

find . -iname '*.jpg' -type f -printf '%b\t%D:%i\n' |
  sort -u | cut -f1 | paste -sd+ - | bc

(size expressed in number of 512 byte blocks). Like du it tries to count hard links only once. If you don't care about hardlinks, you can simplify it to:

(printf 0; find . -iname '*.jpg' -type f -printf +%b) | bc

If you want the size instead of disk usage, replace %b with %s. The size will then be expressed in bytes.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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