Tell me more ×
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.

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.

share|improve this question

2 Answers

up vote 7 down vote accepted

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 like xargs, but find 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.

share|improve this answer

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?.

share|improve this answer

Your Answer

 
discard

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.