10

I would like to see all the unique extension of files contained in a certain directory. What is the command to do that in bash?

One could use find . -type f to get all the files in the current directory, then strip the extension, and pipe it to uniq. What's the easiest way to strip the extension?

14

Try this:

find . -type f | sed -rn 's|.*/[^/]+\.([^/.]+)$|\1|p' | sort -u

It outputs nothing for:

  • Files with no extension
  • Files with names that end in a dot
  • Hidden files

It also might be useful to pipe it to sort | uniq -c.

  • Doesn't work with the default sed on my Mac. I get sed: illegal option -- r – dzhelil Jan 12 '11 at 5:15
  • 8
    @celil: Use -E instead of -r on OS X. – Paused until further notice. Jan 12 '11 at 5:22
3
find . -type f | sed -E 's/.+[\./]([^/\.]+)/\1/' | sort -u

Works on OS X, except for files without extension. My downloads folder:

DS_Store
dmg
exe
localized
msi
nib
plist
pmproj
rar
tgz
txt
webloc
zip

You might need sed -r instead?


Minor issue: Files without extensions print their name. Hidden files (such as .DS_Store) print their name without leading ..

  • I'd recommend sort -u instead of sort | uniq. Less forking and resource usage. – John T Jan 11 '11 at 9:57
  • Thanks @John. Tried to keep within celil's "framework", so I didn't think of it. – Daniel Beck Jan 11 '11 at 10:05
  • It's not necessary to escape a dot inside []. – Paused until further notice. Jan 12 '11 at 3:22
3

Here's yet another solution that does not get confused by file names containing embedded newlines and uses sort -uz to correctly sort file extensions that may have embedded newlines as well:

# [^.]: exclude dotfiles
find . -type f -name "[^.]*.*" -exec bash -c '
   printf "%s\000" "${@##*.}" # get the extensions and nul-terminate each of them
' argv0 '{}' + |
sort -uz | 
tr '\0' '\n' | 
nl
3

A quick and easy to remember way to strip the extension is to asume all filenames have the format "name.ext" then use:

 ls -1 | cut -d"." -f2- | sort | uniq -c

this gives a count of how many unique extensions there are, for example:

   1 sh  
   3 txt  
   4 txt.Z  
  17 dat  
  72 dat.gz  
1

see, that's why I like awk:

find . -type f | awk -F "." '{ print $(NF) }' | sort -u

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.