84

How can I get the size of all files and all files in its subdirectories using the du command.

I am trying the following command to get the size of all files (and files in subdirectories)

find . -type f | du -a

But this prints out the folder sizes as well. How can I get a listing of sizes of all files and files in subdirectories? I also tried the exec flag but I am not sure how to pipe the output into another command after it executes the results of find into du.

The operating system is AIX 6.1 with ksh shell.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

6 Answers6

91

I usually use the -exec utility. Like this:

find . -type f -exec du -a {} +

I tried it both on bash and ksh with GNU find. I never tried AIX, but I'm sure your version of find has some -exec syntax.

The following snippet sorts the list, largest first:

find . -type f -exec du -a {} + | sort -n -r | less
rahmu
  • 20,023
  • 3
    I'd go with this answer if you don't have access to find -print0 or other GNU features. If available, replacing \; with \+ will result in fewer invocations of du and thus better performance. – jw013 Oct 11 '11 at 22:02
  • Thanks, this works out great especially since du offers a flag for size in different units. – Shardul Upadhyay Oct 12 '11 at 12:59
  • I could not find information on the + option. Is that an option for du or for find ? And why does it result in less calls? – Amelio Vazquez-Reina Jul 19 '13 at 22:41
  • 3
    It's a standard option of find. It specifies to exec the command (in our case du) only once, with all the results of find given as successive arguments to the command. – rahmu Jul 20 '13 at 02:25
  • wtf, why isn't there a command like du -f --threshold=1G – Alexander Mills Dec 22 '18 at 03:41
  • the standard -exec option of find is stupid, just get comfortable with xargs instead since xargs is more generic. obviously. – Alexander Mills Dec 22 '18 at 03:42
  • 1
    @AlexanderMillsyou might be interested in this https://unix.stackexchange.com/questions/41740/find-exec-vs-find-xargs-which-one-to-choose – rahmu Apr 16 '19 at 12:55
  • If the # of files is too high, + option will not play well with some du flags (e.g. -c) -- not in the original question, but a likely next step. This is because + does not seem to be guaranteed to result in a single invocation of du: "the total number of invocations of the command will be much less than the number of matched". The # of invocations is probalby dependent on the max command size accepted by the current shell (?). So, behaviour may differ between systems. If you have GNU find/du @jw013's answer should be more reliable and adaptable to different needs that may arise. – m000 Aug 11 '23 at 03:46
22

If you have GNU utilities, try

find . -type f -print0 | du --files0-from=-
jw013
  • 51,212
  • The command is failing saying print0 is not a valid command and that last minus was not a recognized flag. I don't think this approach will work because man du doesn't list a files or from flag. – Shardul Upadhyay Oct 11 '11 at 20:00
  • 1
    You should add your operating system as a tag to the question. I assumed you had GNU but forgot to mention that. – jw013 Oct 11 '11 at 20:04
  • 5
    Have an upvote on me! Your particular solution works with du -ch to get a grand total of matching files: find . -name 'blah blah.*' -print0 | du --files0-from=- -ch – Michael Goldshteyn Jul 15 '18 at 14:05
14

I generally use:

find . -type f -print0 | xargs -r0 du -a

Xargs usually calls the command, even if there are no arguments passed; xargs du </dev/null will still be called, xargs -r du </dev/null will not call du. The -0 argument looks for null-terminated strings instead of newline terminated.

Then I usually add | awk '{sum+=$1} END {print sum}' on the end to get the total.

Arcege
  • 22,536
7

Here's a version with long parameter names and human sorting.

find . -type f -exec du --human {} + | sort --human --reverse | head

I also saw no need for -a/--all to be passed to du.

Tarrasch
  • 216
3

For completeness: The accepted answer does what the question asks for in that it uses du specifically, but please note that du will print out the disk usage (which depends on the block size of the partition where the file is stored), which is not generally the same as the file size (which is constant, no matter where the file is stored). An alternative that prints the number of bytes in the file instead of the disk usage would be find . -type f -printf '%s %f\n' (or find . -type f -printf '%s %f\n' | sort -k2 to sort by name).

-3

specific files in current dir

du -ch files*

is shorter and works for me

du -sh .

for current dir and all files in sub

du (GNU coreutils) 8.30

shorty
  • 1
  • 2
    (1) What do you mean by du -ch files*?  Suppose the current directory contains ant, apple, banana, bat, cat, corn, date, and dog, where the animal names are subdirectories and the fruit / vegetable names are files — what command would you use to get just the files?  Or is that not what you meant? (2) du -sh . will report only a grand total of everything in and under the current directory, and not the files themselves at all.  This is pretty much the exact opposite of what the question asked for. – G-Man Says 'Reinstate Monica' Jan 25 '19 at 23:09