Count files in a directory
Get a count of files (excluding directories) in a folder — at depth 1 or recursively, with hidden files included or excluded.
How to count files in a directory in each shell
find . -maxdepth 1 -type f | wc -l`-maxdepth 1` = depth 1 (current dir only, no subdirs); drop it for full recursion. `-type f` excludes directories. The `ls -1 | wc -l` shortcut is buggy when filenames contain newlines (rare but real) — `find -print0 | tr -cd "\0" | wc -c` is the bullet-proof form using NUL-delimited counting. Hidden files: `find` includes them by default; `ls` excludes them unless `-A`.
ls -1 | wc -lSame external tools as bash. Zsh native: `print -- *(N.) | wc -w` — `*(N.)` is the glob qualifier "files only, null-glob if empty", `wc -w` counts words. For hidden+regular: `*(ND.)`. The `(D)` adds dot-files.
count *Fish `count` builtin counts its arguments — `count *` counts files+dirs at depth 1, `count **` counts recursive incl. files+dirs. To exclude dirs at depth 1: `count (find . -maxdepth 1 -type f)`. For hidden+regular: `count * .*` (the `.*` glob expands to dot-files).
(Get-ChildItem -File).Count`-File` excludes directories; `-Directory` for the inverse. Recursive: `(Get-ChildItem -File -Recurse).Count`. Hidden + system files: `Get-ChildItem -File -Force`. The `.Count` property on the returned `[object[]]` is the canonical idiom; pipeline alternative is `Get-ChildItem -File | Measure-Object | Select-Object -Expand Count`.
dir /a-d /b | find /c /v ""`/a-d` = "attribute NOT directory" (excludes dirs); `/b` = bare format (just filenames, no headers). `find /c /v ""` counts lines that DON'T match empty string (i.e., every line). The full chain reads "list files, count them". For recursion: `dir /s /a-d /b | find /c /v ""`.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- `ls | wc -l` is the canonical-but-broken shortcut: any filename containing a newline character (legal on every Unix) inflates the count. Practical fix when you don't trust filenames: `find . -maxdepth 1 -type f -print0 | tr -dc "\0" | wc -c`. For typical use (no weird filenames), `find . -maxdepth 1 -type f | wc -l` is fine.
- Directories vs files: every shell's default `ls`/`Get-ChildItem` includes BOTH. To count only regular files, every shell needs an explicit filter — `find -type f`, `Get-ChildItem -File`, `dir /a-d`. The `ls -l | wc -l` form ALSO includes the `total N` header line, off-by-one — subtract 1, or use `ls -1`.
- Hidden files behave differently across tools: Unix `find` includes dotfiles by default, `ls` excludes them unless `-A`/`-a`. PowerShell `Get-ChildItem` excludes hidden+system files unless `-Force`. cmd `dir` excludes them unless `/a` (all attributes). Cross-shell consistency requires explicit flags.
- Symlinks count as files (`-type f` matches their target type) or as symlinks (`-type l`) depending on intent. To count symlinks separately: `find . -maxdepth 1 -type l | wc -l`. PowerShell: `Get-ChildItem | Where-Object { $_.LinkType -eq "SymbolicLink" } | Measure-Object`. On Windows, `dir /aL` filters on the "reparse point" attribute (covers symlinks + junctions).
Related commands
Related tasks
- Find files by name— Locate files matching a glob pattern (e.g. `*.log`) anywhere under the current tree.
- List files recursively— Print every file under a directory tree, optionally as a flat list of full paths.
- List the largest directories in a tree— Find the biggest directories anywhere in a tree (not just top-level immediate children) — for tracking down where a node_modules, log dir, or build artifact bloat is hiding deep in a project.