One option is to use find
, but I suggest one of the other solutions shown below.
find /data/dataold/exports -mindepth 1 -maxdepth 1 -exec du -sh {} \;
Assuming that /data/dataold/exports
contains the subdirectories
foo
bar
baz
(and maybe more), it will run
du -sh /data/dataold/exports/foo
du -sh /data/dataold/exports/bar
du -sh /data/dataold/exports/baz
etc.
Option -mindepth
avoids running the du
command for /data/dataold/exports
, and -maxdepth
avoids this for subdirectories of a subdirectory, e.g. for /data/dataold/exports/foo/something
.
As suggested in cas' comment, you can use
find /data/dataold/exports -mindepth 1 -maxdepth 1 -exec du -sh {} \+
instead of ... -exec du -sh {} \;
, if your version of find
supports this. With +
instead of ;
, find
will execute du
once for every time the linux arg buffer is filled (approx 2MB) instead of executing it once for every file/directory. The former is much faster.
Citing Stéphane Chazelas' comment: "Note that calling several independent invocations of du
(like with find -exec
) may give different numbers if there are hard links across those top level directories, as they won't get deduplicated if found by different invocations of du
."
With GNU du
you can limit the depth to be displayed using option -d
or --max-depth=N
:
du -h -d 1 /data/dataold/exports
This will do the calculation for all subdirectories but limit the output to a depth of 1 below the starting point, so in the example shown above it should print the total size for
/data/dataold/exports/foo
/data/dataold/exports/bar
/data/dataold/exports/baz
etc. and for
/data/dataold/exports
The second solution, if available, should be preferred because it doesn't need to start a new du
process for every subdirectory (in case of -exec ... \;
) or for every set of subdirectories that fills up the arguments buffer (in case of -exec ... \+
).
If your version of du
does not support option -d
you can use
du -h /data/dataold/exports
and filter the output to remove everything below the first level of subdirectories.
If you want to filter the output by numeric comparison, I suggest to omit the option -h
. To avoid waiting for the slow file system access while testing the filtering, I suggest to redirect the output to a file, e.g.
du -d 1 /data/dataold/exports > outputfile
or
du -d 1 /data/dataold/exports 2>errors | tee outputfile
and process the contents of outputfile
later.
Example:
awk '$1 > 20e9` outputfile
If your du
doesn't support option -d
you could use something like
du /data/dataold/exports > outputfile
awk '$1 > 20e9 && $1 != /\/.*\/.*\/.*\/.*\/.*/` outputfile
This will print all lines that have a number bigger than 20 * 10^9 in the first field and a value that does not contain 5 (or more) slashes in the second field. The number of slashes in the second condition is tailored to the starting directory /data/dataold/exports
and will print e.g. /data/dataold/exports/foo
but not e.g. /data/dataold/exports/foo/bar
.
ncdu
is a very nice utility for this purpose.du -hd1
work? That tellsdu
to list each first-level subdirectory itself, rather than first having the shell enumerate them and try to pass the entire list as arguments.