Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to write a shell script or alias to find the number of different types of files in a directory. For example, sample output of script should be:

*.h      20
*.c      40
*.cpp    10
Makefile 3
share|improve this question
up vote 7 down vote accepted
find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr

The echo ${0##*.} gives you the extension of the file. We pipe the output to sort and then count the unique lines with uniq.

Some additions:

  • Since the output of uniq is not sorted according to the number of occurrences, you'll have to pipe again into a numeric sort (-nr) if you want it sorted.
  • If you want to search your current directory only, add -maxdepth 1 to your find command.
  • Pipe into awk '{print $2, $1}' to show the count after the extensions.
share|improve this answer
Nice answer. This will not include files without extensions. Is there a simple way to find that? – jaychris Sep 4 '13 at 17:02
The -name '*.*' option restricts find to files with extensions only. If you leave this out, you'll end up with a count of 1 for every file though, so this might not be ideal. – slhck Sep 4 '13 at 17:03
You could add a branch in the sh to check if it has an extension, if so print extension, if not print full filename; and find * – Clayton Stanley Sep 5 '13 at 5:27
@ClaytonStanley Since the extra sh process takes a little more execution time, filtering the results with find will be a little faster, I guess. – slhck Sep 5 '13 at 5:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .