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.
2 Answers
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:
- Firstly,
cd
to the directory that you want to count all files with specific extension in. - 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:
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 asb?-file.txt
in the "Finder", i.e. A question mark indicates the newline in a multi-line filenameThen run the following command that pipes the results of
find
towc -l
:find ~/Desktop/test -name "*.txt" | wc -l
It incorrectly reports/prints:
6
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

- 22,977
- 20
- 73
- 80