- How can I get a count of files in a directory using the command line?
- 20 Answers 20
- Count Number of Files in a Directory in Linux
- Count number of files in directory in Linux
- Count number of files and directories (without hidden files)
- Count number of files and directories including hidden files
- Count number of files and directories including the subdirectories
- Count only the files, not directories
- Count only the files, not directories and only in current directory, not subdirectories
- Fast way to find the number of files in one directory on Linux
How can I get a count of files in a directory using the command line?
I have a directory with a large number of files. I don’t see a ls switch to provide the count. Is there some command line magic to get a count of files?
tree . | tail or tree -a . | tail to include hidden files/dirs, tree is recursive if that’s what you want.
@CodyChan : It should be tail -n 1 , and even then the count would also include the entries in subdirectories.
20 Answers 20
Using a broad definition of «file»
(note that it doesn’t count hidden files and assumes that file names don’t contain newline characters).
To include hidden files (except . and .. ) and avoid problems with newline characters, the canonical way is:
find . ! -name . -prune -print | grep -c /
find .//. ! -name . -print | grep -c //
wc is a «word count» program. The -l switch causes it to count lines. In this case, it’s counting the lines in the output from ls . This is the always the way I was taught to get a file count for a given directory, too.
that doesn’t get everything in a directory — you’ve missed dot files, and collect a couple extra lines, too. An empty directory will still return 1 line. And if you call ls -la , you will get three lines in the directory. You want ls -lA | wc -l to skip the . and .. entries. You’ll still be off-by-one, however.
A corrected approach, that would not double count files with newlines in the name, would be this: ls -q | wc -l — though note that hidden files will still not be counted by this approach, and that directories will be counted.
For narrow definition of file:
find . -maxdepth 1 -type f | wc -l
And you can of course omit the -maxdepth 1 for counting files recursively (or adjust it for desired max search depth).
A corrected approach, that would not double count files with newlines in the name, would be this: find -maxdepth 1 -type f -printf «\n» | wc -l
I have found du —inodes useful, but I’m not sure which version of du it requires. It should be substantially faster than alternative approaches using find and wc .
On Ubuntu 17.10, the following works:
du --inodes # all files and subdirectories du --inodes -s # summary du --inodes -d 2 # depth 2 at most
Combine with | sort -nr to sort descending by number of containing inodes.
Thanks for sharing! I searched for «count» in the du man page, as in «I want to count the files», but it’s not documented with that word. Any answer using wc -l will be wrong when any name contains a newline character.
$ ls --help | grep -- ' -1' -1 list one file per line
$ wc --help | grep -- ' -l' -l, --lines print the newline counts
@Dennis that’s interesting I didn’t know that an application could tell its output was going to a pipe.
I +’ed this version since it is more explicit. Though, yes ls does use -1 if it’s piped (try it: ls | cat), I find the -1 syntax more explicit.
In my tests it was significantly faster to also provide the -f option to avoid ls sorting the filenames. Unfortunately you still get the wrong answer if your filenames contain newlines.
Probably the most complete answer using ls / wc pair is
if you want to count dot files, and
- -A is to count dot files, but omit . and .. .
- -q make ls replace nongraphic characters, specifically newline character, with ? , making output 1 line for each file
To get one-line output from ls in terminal (i.e. without piping it into wc ), -1 option has to be added.
(behaviour of ls tested with coreutils 8.23)
As you said, -1 is not needed. As to «it handles newlines in filenames sensibly with console output», this is because of the -q switch (that you should use instead of -b because it’s portable) which «Forces each instance of non-printable filename characters and characters to be written as the ( ‘?’ ) character. Implementations may provide this option by default if the output is to a terminal device.» So e.g. ls -Aq | wc -l to count all files/dirs or ls -qp | grep -c / to count only non-hidden dirs etc.
Currently includes directories in its file count. To be most complete we need an easy way to omit those when needed.
@JoshHabdas It says «probably». 😉 I think the way to omit directories would be to use don_crissti’s suggestion with a slight twist: ls -qp | grep -vc / . Actually, you can use ls -q | grep -vc / to count all (non-hidden) files, and adding -p makes it match only regular files.
If you know the current directory contains at least one non-hidden file:
This is obviously generalizable to any glob.
In a script, this has the sometimes unfortunate side effect of overwriting the positional parameters. You can work around that by using a subshell or with a function (Bourne/POSIX version) like:
count_words () < eval 'shift; '"$1"'=$#' >count_words number_of_files * echo "There are $number_of_files non-dot files in the current directory"
An alternative solution is $(ls -d — * | wc -l) . If the glob is * , the command can be shortened to $(ls | wc -l) . Parsing the output of ls always makes me uneasy, but here it should work as long as your file names don’t contain newlines, or your ls escapes them. And $(ls -d — * 2>/dev/null | wc -l) has the advantage of handling the case of a non-matching glob gracefully (i.e., it returns 0 in that case, whereas the set * method requires fiddly testing if the glob might be empty).
If file names may contain newline characters, an alternative is to use $(ls -d ./* | grep -c /) .
Any of those solutions that rely on passing the expansion of a glob to ls may fail with a argument list too long error if there are a lot of matching files.
Count Number of Files in a Directory in Linux
Here are several ways to count the number of files in a directory in Linux command line.
I presume you are aware of the wc command for counting number of lines. We can use the same wc command with ls command to count the number of files in a directory.
This task seems simple but could soon turn slightly complex based on your need and definition of counting files. Before I confuse you further, let’s see about various use cases of counting the number of files in Linux.
Count number of files in directory in Linux
Let me first show you the content of the test directory I am going to use in this tutorial:
[email protected]:~/tutorials$ ls -la total 64 drwxr-xr-x 4 abhishek abhishek 4096 Apr 29 17:53 . drwxr-xr-x 55 abhishek abhishek 4096 Apr 29 15:50 .. -rwxr–r– 1 abhishek abhishek 456 Mar 6 16:21 agatha.txt -rw-r–r– 1 abhishek abhishek 0 Apr 16 19:53 .a.t -rwxr–r– 1 abhishek abhishek 140 Mar 22 16:41 bash_script.sh -rw-rw-r– 1 abhishek abhishek 95 Feb 11 13:12 cpluplus.cpp -rw-r–r– 1 abhishek abhishek 1778 Apr 29 16:16 my_zip_folder.zip drwxr-xr-x 4 abhishek abhishek 4096 Apr 19 19:07 newdir -rw-r–r– 1 abhishek abhishek 163 Apr 13 15:07 prog.py -rw-r–r– 1 abhishek abhishek 19183 Mar 18 18:46 services -rw-r–r– 1 abhishek abhishek 356 Dec 11 21:35 sherlock.txt -rwxrw-r– 1 abhishek abhishek 72 Jan 21 15:44 sleep.sh drwxr-xr-x 3 abhishek abhishek 4096 Jan 4 20:10 target
You can see that it has 9 files (including one hidden file) and 2 sub-directories in that directory. But you don’t have to do it manually. Let’s count the number of files using Linux commands.
Count number of files and directories (without hidden files)
You can simply run the combination of the ls and wc command and it will display the number of files:
There is a problem with this command. It counts all the files and directories in the current directories. But it doesn’t see the hidden files (the files that have name starting with a dot).
This is the reason why the above command showed me a count of 10 files instead of 11 (9 files and 2 directories).
Count number of files and directories including hidden files
You probably already know that -a option of ls command shows the hidden files. But if you use the ls -a command, it also displays the . (present directory) and .. (parent directory). This is why you need to use -A option that displays the hidden files excluding . and .. directories.
This will give you the correct count of files and directories in the current directory. Have a look at the output that shows a count of 11 (9 files and 2 directories):
You can also use this command to achieve the same result:
Note that it the option used is 1 (one) not l (L). Using the l (L) option displays an additional line at the beginning of the output (see ‘total 64’ in the directory output at the beginning of the article). Using 1 (one) lists one content per line excluding the additional line. This gives a more accurate result.
Count number of files and directories including the subdirectories
What you have see so far is the count of files and directories in the current directory only. It doesn’t take into account the files in the subdirectories.
If you want to count the number of files and directories in all the subdirectories, you can use the tree command.
This command shows the directory structure and then displays the summary at the bottom of the output.
[email protected]:~/tutorials$ tree -a . ├── agatha.txt ├── .a.t ├── bash_script.sh ├── cpluplus.cpp ├── my_zip_folder.zip ├── newdir │ ├── new_dir │ │ ├── c.xyz │ │ ├── myzip1.zip │ │ └── myzip2.zip │ └── test_dir │ ├── c.xyz │ ├── myzip1.zip │ └── myzip2.zip ├── prog.py ├── services ├── sherlock.txt ├── sleep.sh └── target ├── agatha.txt ├── file1.txt └── past ├── file1.txt ├── file2.txt └── source1 └── source2 └── file1.txt 7 directories, 19 files
As you can see in the output, it shows that there are 7 directories and 20 files in total. The good thing about this result is that it doesn’t count directories in the count of files.
Count only the files, not directories
So far, all the solutions we have seen for counting the number of files, also take directories into account. Directories are essentially files but what if you want to count only the number of files, not directories? You can use the wonderful find command.
The above command searched for all the files (type f) in current directory and its subdirectories.
[email protected]:~/tutorials$ find . -type f | wc -l 20
Count only the files, not directories and only in current directory, not subdirectories
That’s cool! But what if you want to count the number of files in the current directory only excluding the files in the subdirectories? You can use the same command as above but with a slight difference.
All you have to do is to add the ‘depth’ of your find. If you set it at 1, it won’t enter the subdirectories.
find . -maxdepth 1 -type f | wc -l
[email protected]:~/tutorials$ find . -maxdepth 1 -type f | wc -l 9
In Linux, you can have multiple ways to achieve the same goal. I am pretty sure there can be several other methods to count the number of files in Linux. If you use some other command, why not share it with us?
I hope this Linux tutorial helped you learn a few things. Stay in touch for more Linux tips.
Fast way to find the number of files in one directory on Linux
I am looking for a fast way to find the number of files in a directory on Linux. Any solution that takes linear time in the number of files in the directory is NOT acceptable (e.g. «ls | wc -l» and similar things) because it would take a prohibitively long amount of time (there are tens or maybe hundreds of millions of files in the directory). I’m sure the number of files in the directory must be stored as a simple number somewhere in the filesystem structure (inode perhaps?), as part of the data structure used to store the directory entries — how can I get to this number? Edit: The filesystem is ext3. If there is no portable way of doing this, I am willing to do something specific to ext3.
Almost duplicate: stackoverflow.com/questions/1427032/…, talks about how to speed up the standard ls | wc-l
I don’t think that this is stored somewhere as a plain number.(I did NOT read the spec though). Simply because it would slow down the FS, you would need to synchronize touch/unlink/mv etc. to get a reliable result, also in case of a crash the number could be corrupted, so you would need to recount the files at some point. Also, at least on my Ubuntu Nautilus caches the number of objects in a directory by itself, if there would be a number in the underlying FS I don’t think it would do that.
I’m wondering. is the size of the directory entry (i.e. the size you see for the directory when you do ls -l in its parent directory) related to the number of entries? It does seem to be larger than usual for this directory.
the size of directory can be correlated with max number of files what was ever stored in it. Directory in a way is a plain file containing sparse array with pointers to actual files.
«tens or maybe hundreds of millions of files» is a pathological case. A large number of files in a directory does affect performance; this is why /usr/share/terminfo has a subdirectory for each initial character used by an entry, so it can be traversed more like a tree to keep file counts down. There are filesystems that are more akin to a database, where the count boils down to a single fast query, but those aren’t common (if they exist at all, IDK) in the Unix world.