How to list ALL directories according to their size? [without including the parent directory]
Solution 1
Parsing the output of ls
is always problematic. You should always use a different tool if you mean to process the output automatically.
In your particular case, your command was failing -- not because of some missing or incompatible argument to ls
-- but because of the glob you were sending it. You were asking ls
to list all results including hidden ones with -a
, but then you were promptly asking it to only list things that matched the */
glob pattern which does not match things beginning with.
and anything ls
might have done was restricted to things that matched the glob. You could have used .*/
as a second glob to match hidden directories as well, or you could have left the glob off entirely and just let ls
do the work. However, you don't even need ls
for this if you have a glob to match.
One solution would be to skip the ls
entirely and just use shell globing:*
$ du -s */ .*/ | sort -n
Another way which might be overkill for this example but is very powerful in more complex situations would be to use find
:*
$ find ./ -type d -maxdepth 1 -exec du -s {} + | sort -n
Explanation:
-
find ./
starts a find operation on the current directory. You could use another path if you like. -
-type d
finds only things that are directories -
-maxdepth 1
tells it only to find directories in the current directory, not to recurse down to sub-directories. -
-exec [command] [arguments] {} +
works much likexargs
, butfind
gets to do all the heavy lifting when it comes to quoting and escaping names. The{}
bit gets replaced with the results from the find. -
du -s
you know
* Note that I used the -n
operator for sort
to get a numeric sorting which is more useful in than alphabetic in this case.
Solution 2
In zsh, use the D
glob qualifier to include dot files in a filename pattern:
du -s -- *(D) | sort -k1n
In bash, set the dotglob
option to make *
match dot files:
shopt -s dotglob
du -s -- * | sort -k1n
In ksh, set FIGNORE
to .?(.)
to ignore only .
and ..
and not other dot files.
FIGNORE='.?(.)'
du -- * | sort -k1n
See also How do you move all files (including hidden) in a directory to another?.
Related videos on Youtube
Karthick
wannabe code monkey. upcoming Keyboard-Ninja. Linux user.
Updated on September 18, 2022Comments
-
Karthick over 1 year
I have a bunch of random folders, some of them are hidden (beginning with a period). I want to list all of them, sorted by their sizes.
I have something on the lines of this in mind:
ls -d -1 -a */ | xargs du -s | sort
But the
ls ...
part of it doesn't show hidden files. I know some questions have been asked before on the same topic, but the answers never include a way to include hidden files. Or if it does, it uses the long format, hence making the output incompatible with the rest of the command. -
Hendy about 10 yearsAre you saying that
du -s */ .*/
should list the sizes of hidden directories? I'm in~/
and issuing the command above (both with and without the pipe tosort
afterward), and only get non-hidden directories, along with./
included in the results (but none of the other ~100 directories starting with.
thatls -a
shows). -
tcoolspy about 10 years@Hendy Yes it should (and does for me). It's possible there are options that need to be set (or unset) for it to work is your shell. What shell are you actually using and what version?
echo $SHELL ; $SHELL --version
-
Hendy about 10 yearsArch Linux system that's updated pretty regularly.
echo $SHELL
:/bin/bash
,$SHELL --version
:GNU bash, version 4.3.11(1)-release (x86_64-unknown-linux-gnu)
. Usingurxvt
terminal; replicated withxterm
as well (not that it should matter). If I dodu -s .*/
on it's own, it only picks up./
and../
. -
Hendy about 10 yearsInterestingly,
du -s .*/*
will pick up all second level contents of hidden directories. So I get itemized contents like.cache/{Flash_Player, chromium, dconf, Thunar, etc.}
. Leaving off the trailing*
doesn't get the top level.cache
dir for some reason! -
tcoolspy about 10 years@Hendy That would indicate you don't have extended glob pattern matching turned on.The terminal would have no effect on this, it is a shell and shell glob expansion options thing. I use ZSH not Bash but I think you can enable the feature in bash with
shopt -s extglob
. -
Hendy about 10 yearsThanks for the tip. I think it would be helpful for you to say that in your answer. If you had stated you were using
zsh
, I would have either 1) dug into whether or not that was the cause of the discrepancy or 2) moved on to another possible solution, assuming that was the cause, not caring to invest more time in figuring that out definitively.