How to Count Files in a Directory in Linux?

Converging file entries flowing into one line counter

A directory count changes with the definition behind it. Pipe ls into wc -l and a directory with nine visible files and two hidden ones reports thirteen, because plain ls does not print dot-prefixed entries. Every number quoted beside a command below comes from that tree.

What You Need Before Piping Anything

Every command here runs on any current Linux desktop or server distribution, no packages required up front. The counting questions on this page break down as follows, one command each.

  • Every visible item in one directory, covered by ls piped into wc.
  • Only the regular files, with directories filtered out by type or by the long listing format.
  • Everything below the starting point, which is a recursive find walk.
  • Depth, extension, hidden entries, and the rsync stat report round out the set.

Read permission on every subdirectory matters too, because it changes the number rather than breaking the command, and the chmod and chown commands explain how that boundary itself gets set.

Counting Every Item in a Directory

ls prints one line per visible entry and wc -l counts the newline characters those lines carry, so the pipe turns a listing into a tally. The Linux command line basics page covers the rest of what each flag on it does.

ls <PATH> | wc -l
Count Files Item Count
Total item count in a directory

Reading the count means reading two commands together. The ls command lists contents and the wc command counts lines in whatever text reaches it, so whatever you pass as PATH, each visible entry lands on its own line and one number comes back.

ls | wc -l without a path counts the directory you are standing in. The shortcut is safe because ls with no argument still prints one entry per line once wc sits on the other end of the pipe.

Anything whose name starts with a dot never reaches the pipe, so the figure undershoots whenever hidden entries exist in the directory. Section five shows the flag that brings them back.

Count on this treeCommandResult
Visible entriesls PATH | wc -l13
Everything including hidden entriesls -A PATH | wc -l14

Counting Files Only, Skipping Directories

A plain ls count mixes files, directories, and links into one number. Separating them needs the long listing format, because it puts one character at the start of every line and that character says what the entry is.

ls -l <PATH> | grep "^[+-]" | wc -l
Count Files Only Files
File count in a directory
Count Files Ls L Edited 1
Output of ‘ls -l ~’

The long-format output in the second screenshot shows why the matching rule works. Every regular file opens its line with a dash, every directory with a d, and links with an l, so grep filtering for lines that start with a dash strips directories out of the count mechanically. The plus sign in the filter covers a rare case: on some filesystems a plus sign replaces the final permission character when the file carries extended ACLs, and that entry is still a regular file.

A final boundary goes with this one: it counts only the top level. Files sitting inside a subdirectory of PATH never enter the long listing, which is exactly the reason section six exists.

Counting Files Recursively With find

The find command walks the whole tree from a starting directory, not just its top level. Piping its output into the same line counter turns a directory walk into a grand total.

find <PATH> -type f | wc -l
Count Files Find Command
Total count of files

The -type f option filters the walk down to regular files, so directories and symlinks never reach the counter. A symlink that points at an existing file still prints as its link type and stays out, which is the behavior you want when the question is how many regular files exist, not how many names point at them.

Unreadable subdirectories change this count’s shape, because find prints a permission denied diagnostic on stderr, keeps walking the rest of the tree, and covers only what it could read.

On a directory owned by another user, placing sudo before find lets the walk descend everything, and the number can grow. The users and groups crash course explains who holds that read bit.

Hidden files cost no extra flag here, because find reports every regular file including dot-prefixed ones. The grand total is therefore usually larger than the top-level count from the plain ls pipe minus the directories.

QuestionCommand shapeBoundary
Only files, everywhere below PATHfind PATH -type f | wc -lSkips directories and links
Include the directories toofind PATH | wc -lOne line per object, the starting directory included
Only directoriesfind PATH -type d | wc -lCounts the starting directory itself

Counting to One Depth With -maxdepth

When the question is how many files this directory holds without counting anything nested below it, add -maxdepth 1 to the walk. This combination returns the same set the ls-and-grep approach counts, but it keeps find’s type filter so the distinction between files and directories stays exact.

find <PATH> -maxdepth 1 -type f | wc -l
Hidden files counted with ls -A piped to wc -l shows 14 entries where plain ls showed 13
Counting hidden files with ls -A in the example directory

The screenshot shows the same tree walked with a depth limit: 9 files at the top level exactly matches the grep count from section three, and dropping -maxdepth lifts the total to 18 because the subdirectories carry the rest. Same directory, two valid numbers, and the difference is the definition you pick for files.

An option called -mindepth works the other way. -mindepth 1 skips the starting directory itself from the walk, which matters when you are counting the entries inside it rather than the directory itself as a filesystem object.

Reading the Whole Tree as a Summary With tree

The tree command draws the directory structure and ends its output with one summary line that carries the file and directory totals, so you can see the shape and the count at the same time. It is not preinstalled on a default Ubuntu system.

Ubuntu and Debian users install it through apt:

sudo apt install tree

On other distributions the package name stays tree, so pacman, dnf, and zypper all take it directly.

After installation one command produces the full picture:

tree <PATH>
Count Files Tree Command
Count files using tree command
tree summary line showing 8 directories and 17 files in the example directory
The tree command summary count for the example directory

The tree above reports 8 directories and 17 files, and 17 stops short of find’s 18 because tree skips dot-prefixed entries by default. Compared with tree -a the summary reads 19, one above find’s total, because tree counts the symlink alias_link.log as a file while find -type f keeps links out of the figure.

Another boundary matters when a count feeds an alert or a script, because tree’s total stops at 26 levels and prints a not listed note past that floor. find reports the full figure on the same deep tree, so the two commands disagree by whatever lives below that floor.

ToolWhat the summary line reportsHidden entries
tree PATH8 directories, 17 filesSkipped without -a
tree -a PATH8 directories, 19 filesCounted, links included
rsync –stats18 regular files, 8 directories, 1 linkAll counted

Counting by File Type With find -name

Extension-scoped counting answers a different question: how many of the files in this tree end in .log, .pdf, or whatever suffix you are hunting for. The recursive count extends with one more filter.

find <PATH> -type f -name "*.log" | wc -l

Quote the -name option’s argument so the shell does not expand the asterisk before find sees it. The count in the example directory comes back 7, the number of log files spread across three levels including the one nested two levels deep in the archive folder.

Swap the option argument for -name “*.pdf” and the same structure reports 3, since filename matching is case-sensitive by default. Mixed-case extensions like .JPG and .jpg count together only under -iname.

rsync --stats report showing 27 total items split into 18 regular files, 8 directories and 1 link
The rsync stat report for the example directory

The same walk, reported differently. rsync is a transfer tool, but pointed at a directory with –stats and –dry-run it computes the file inventory it would have copied and reports it instead, so one stat line splits a tree into its regular files, directories, and links.

rsync --stats --dry-run -a <PATH>

The Number of files line in the screenshot carries three numbers in one: 18 regular files, 8 directories, and 1 link in the example tree. Nothing gets created or deleted, because –dry-run stages the transfer and reports the statistics without touching a byte. On large trees this runs faster than a nested walk because rsync’s file scanner is built for exactly this traversal, and the same walk reports per-directory totals in a disk and memory usage monitor.

When you want a directory-only sibling of section six, find <PATH> -type d | wc -l counts directories at every depth including the starting one, and pairing it with the -type f count tells you how the tree splits.

Handing a Count to a Script

A count becomes useful when the next step consumes it. Command substitution wraps the whole pipeline in dollars and parentheses so a script can hold the number in a variable, the same substitution the bashrc guide uses for startup checks.

#!/bin/bash
count=$(find "$1" -maxdepth 1 -type f | wc -l)
echo "$count files at the top level"

The screenshot’s example directory is what this script points at, and the output line carries the top-level file count as its first token. Double quotes around $1 keep a directory name with spaces intact, which matters when the argument comes from a user’s home folder. To consume the count in a condition rather than print it, replace the echo with a test like if [ “$count” -gt 0 ], and add -A to the ls variants when the hidden entries belong to it.

Broken Links and Files the Count Skipped

Directory content of two kinds produces a figure that is technically right and practically wrong. Both deserve a check before you feed either figure to a script.

  • A symlink whose target is gone still enters a plain ls count and shows up as -type l in rsync’s report, but never enters an -type f figure, which is why the methods can disagree by one on the same directory. The file editing guide covers what a script can assume about targets like that.
  • A subdirectory whose permissions lock the walk shrinks a find total on stderr-free runs and prints permission denied diagnostics when it happens.

Counting once with stderr visible settles whether the figure in front of you is the whole tree or a readable part of it.

The Count To Hand To The Next Command

Each of these produces a truthful number for its own definition, so write the definition into the pipeline before you reuse it anywhere. Top level only says find -maxdepth 1 -type f. Everything below it drops the -maxdepth flag, and hidden entries ride along with no extra flag once find is on the job.

Next thing to try: point find at a directory you thought was empty and run the count with and without -maxdepth 1, because that disagreement on a path you considered empty points straight at files a cleanup job missed.

How can I count the number of files in a directory on Linux?

Pipe ls into wc -l. The command ls | wc -l counts all visible entries in the current directory, and adding a path counts a different directory. Each entry lands on one line, so the line count is the entry count.

How can I count hidden files using Linux commands?

Plain ls skips every name that starts with a dot. Replace it with ls -A | wc -l to include those entries while keeping the special . and .. entries out of the count, or use find -type f | wc -l which never skips dot files in the first place.

Is there a way to count files and directories recursively in Linux?

Yes. find . -type f | wc -l counts every regular file under the current directory including all subdirectories. Drop the -type f when directories belong in the count as well, and tree . prints the summary line with both numbers at once.

Can I count only files in a specific directory without including subdirectories?

Yes. find /path -maxdepth 1 -type f | wc -l counts only regular files directly inside that directory, or ls -l | grep ‘^[+-]’ | wc -l reaches the same number through the long listing format.

How do I count files in a directory using a bash script?

Wrap the pipeline in command substitution. count=$(find “$1” -maxdepth 1 -type f | wc -l) stores the number in count when $1 is the directory argument, and the script can echo it or apply a test to it.

Why does the find count show a permission denied error?

find cannot descend into a subdirectory your user is not allowed to read, so files under it stay uncounted. Place sudo before the find command to walk the full tree, or accept that the count covers only the readable part of the tree.

How can I count files of a specific type in Linux?

Add a filename filter to the walk. find /path -type f -name “*.log” | wc -l counts only regular files ending in .log, and -iname makes the match ignore case so both JPG and jpg count together.

What is a fast way to count all files including links and directories?

rsync –stats –dry-run -a /path reports one stat line that splits the tree into regular files, directories, and links. Nothing is transferred because –dry-run stops the copy before it starts.

Can I count files in Linux without using the terminal?

Yes. GNOME’s Files and KDE’s Dolphin both show the item count for a selected folder in their properties dialog, and the status bar usually states it while you browse. Those counts include nested files at the cost of opening the dialog first.