Search code examples
unixgrepag

Recursively finding files in list of directories


How do I recursively count files in a list of Linux directories?

Example:

/dog/
  /a.txt
  /b.txt
  /c.ipynb

/cat/
  /d.txt
  /e.pdf
  /f.png
  /g.txt

/owl/
  /h.txt

I want following output:

5 .txt
1 .pynb
1 .pdf
1 .png

I tried the following, with no luck.

find . -type f | sed -n 's/..*\.//p' | sort | uniq -c

Solution

  • This find + gawk may work for you:

    find . -type f -print0 |
    awk -v RS='\0' -F/ '{sub(/^.*\./, ".", $NF); ++freq[$NF]} END {for (i in freq) print freq[i], i}'
    

    It is safe to use -print0 in find to handle files with whitespace and other special glob characters. Likewise we use -v RS='\0' in awk to ensure NUL byte is record seperator.