Getting all extensions for a directory: easy. Getting file counts for a particular extension: easy.

But getting all file extensions and their respective file counts is alluding me.


+ dir
 + abc.txt
 + def.txt
 + abc.pdf
 * def.pov

should return something like:

.txt 2
.pdf 1
.pov 1

The aim of this exercise is that I want to find out which file extension is popular in a certain directory.

Thanks in advance

3 Answers 3

/var/cache$ sudo find ./ -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq -c | sort -n
      1 .6
      1 .cache
      1 .noconf
      1 .php
      1 .sl
      2 .bin
      2 .el
      2 .tdb
      4 .baseA
      4 .baseB
      4 .dat
      4 .DB
     27 .db
    221 .deb

Here is the explication:

find ./ -type f

find only file, not directory

grep -E ".*\.[a-zA-Z0-9]*$"

filter file with extension

sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/'

delete path and file name, save only extension

sort | uniq -c | sort -n

sort, uniq and sort

  • You could make your regex allow more characters in the extension and eliminate grep by doing this: sed -ne '/\.[^./]*$/s/.*\(\.[^.]*\)$/\1/p' Sep 22, 2010 at 6:17
  • Dennis, replacing the grep and sed with your sed returns the following error: sed: -e expression #1, char 30: invalid reference \1 on `s' command's RHS Sep 23, 2010 at 1:09

Since you're using Linux (gnu grep), this is a good time to use Perl REs (PCRE) -P and grep's -o option. Taking @bindbn's answer as a great candidate:

find . -type f | grep -Po '\.([\w\d])*$' | sort | uniq -c | sort -n

I just had the same problem and came up with this solution:

find . -type f | rev | cut -d "." -f 1 | rev | sort | uniq -c | sort -n

This is very similar to the other solutions proposed here, but perhaps easier to understand/remember and maybe slightly faster. It also avoids the usual headaches with filenames containing special characters.

rev | cut -d "." -f 1 | rev reverses the filename string, extracts the (reversed) file extension up to the "." delimiter, and reverses back the extension substring, then sort | uniq -c | sort -n counts the instances of each extension and prints the result in ascending order of matches.

You must log in to answer this question.

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