41

I use ls -l *.filetype | wc -l but it can only find files in current directory.
How can I also count all files with specific extension in its sub dirs?
Thank you very much.

athspk
  • 6,722
  • 7
  • 37
  • 51
Xitrum
  • 7,765
  • 26
  • 90
  • 126

2 Answers2

92

You can do that with find command:

find . -name "*.filetype" | wc -l
P.P
  • 117,907
  • 20
  • 175
  • 238
1

The following compound command, albeit somewhat verbose, guarantees an accurate count because it handles filenames that contain newlines correctly:

total=0; while read -rd ''; do ((total++)); done < <(find . -name "*.filetype" -print0) && echo "$total"

Note: Before running the aforementioned compound command:

  1. Firstly, cd to the directory that you want to count all files with specific extension in.
  2. Change the filetype part as appropriate, e.g. txt

Demo:

To further demonstrate why piping the results of find to wc -l may produce incorrect results:

  1. Run the following compound command to quickly create some test files:

    mkdir -p ~/Desktop/test/{1..2} && touch ~/Desktop/test/{1..2}/a-file.txt && touch ~/Desktop/test/{1..2}/$'b\n-file.txt'
    

    This produces the following directory structure on your "Desktop":

    test
    ├── 1
    │   ├── a-file.txt
    │   └── b\n-file.txt
    └── 2
        ├── a-file.txt
        └── b\n-file.txt
    

    Note: It contains a total of four .txt files. Two of which have multi-line filenames, i.e. b\n-file.txt.

    On newer version of macOS the files named b\n-file.txt will appear as b?-file.txt in the "Finder", i.e. A question mark indicates the newline in a multi-line filename

  2. Then run the following command that pipes the results of find to wc -l:

    find ~/Desktop/test -name "*.txt" | wc -l
    

    It incorrectly reports/prints:

    6

  3. Then run the following suggested compound command:

    total=0; while read -rd ''; do ((total++)); done < <(find ~/Desktop/test -name "*.txt" -print0) && echo "$total"
    

    It correctly reports/prints:

    4

RobC
  • 22,977
  • 20
  • 73
  • 80