Count files in a directory by extension

My approach would be:

  1. List all files in the directory
  2. Extract their extension
  3. Sort the result
  4. Count the occurrences of each extension

Sort of like this (last awk call is purely for formatting):

ls -q -U | awk -F . '{print $NF}' | sort | uniq -c | awk '{print $2,$1}'

(assuming GNU ls here for the -U option to skip sorting as an optimisation. It can be safely removed without affecting functionality if not supported).


This recursively traverses files and counts extensions that match:

$ find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
   6 tiff
   7 bmp
  26 jpeg
  38 gif
  51 jpg
  54 png

I'd suggest a different approach, avoiding the possible word-splitting issues of ls

#!/bin/bash

shopt -s nullglob

for ext in jpg png gif; do 
  files=( *."$ext" )
  printf 'number of %s files: %d\n' "$ext" "${#files[@]}"

  # now we can loop over all the files having the current extension
  for f in "${files[@]}"; do
    # anything else you like with these files
    :
  done 

done

You can loop over the files array with any other commands you want to perform on the files of each particular extension.


More portably - or for shells that don't provide arrays explicitly - you could re-use the shell's positional parameter array i.e.

set -- *."$ext"

and then replace ${#files[@]} and ${files[@]} with $# and "$@"