Find the number of files in a directory

2019-03-22 17:01发布

Is there any method in Linux to calculate the number of files in a directory (that is, immediate children) in O(1) (independently of the number of files) without having to list the directory first? If not O(1), is there a reasonably efficient way?

I'm searching for an alternative to ls | wc -l.

8条回答
干净又极端
2楼-- · 2019-03-22 17:37

use ls -1 | wc -l

查看更多
ゆ 、 Hurt°
3楼-- · 2019-03-22 17:42

For the number of all file in a current directory try this:

ls -lR * | wc -l
查看更多
老娘就宠你
4楼-- · 2019-03-22 17:43

I think you can have more control on this using find:

find <path> -maxdepth 1 -type f -printf "." | wc -c
  • find -maxdepth 1 will not go deeper into the hierarchy of files.
  • -type f allows filtering to just files. Similarly, you can use -type d for directories.
  • -printf "." prints a dot for every match.
  • wc -c counts the characters, so it counts the dots created by the print... which means counting how many files exist in the given path.
查看更多
成全新的幸福
5楼-- · 2019-03-22 17:45

One can get the number of subdirectories of a given directory without traversing the whole list by stat'ing (stat(1) or stat(2)) the given directory and observing the number of links to that directory. A given directory with N child directories will have a link count of N+2, one link for the ".." entry of each subdirectory, plus two for the "." and ".." entries of the given directory.

However one cannot get the number of all files (whether regular files or subdirectories) without traversing the whole list -- that is correct.

The "/bin/ls -1U" command will not get all entries however. It will get only those directory entries that do not start with the dot (.) character. For example, it would not count the ".profile" file found in many login $HOME directories.

One can use either the "/bin/ls -f" command or the "/bin/ls -Ua" command to avoid the sort and get all entries.

Perhaps unfortunately for your purposes, either the "/bin/ls -f" command or the "/bin/ls -Ua" command will also count the "." and ".." entries that are in each directory. You will have to subtract 2 from the count to avoid counting these two entries, such as in the following:

expr `/bin/ls -f | wc -l` - 2     # Those are back ticks, not single quotes.

The --format=single-column (-1) option is not necessary on the "/bin/ls -Ua" command when piping the "ls" output, as in to "wc" in this case. The "ls" command will automatically write its output in a single column if the output is not a terminal.

查看更多
Evening l夕情丶
6楼-- · 2019-03-22 17:48

I used this command..works like a charm..only to change the maxdepth..that is sub directories

find * -maxdepth 0 -type d -exec sh -c "echo -n {} ' ' ; ls -lR {} | wc -l" \;
查看更多
Bombasti
7楼-- · 2019-03-22 17:50

readdir is not as expensive as you may think. The knack is avoid stat'ing each file, and (optionally) sorting the output of ls.

/bin/ls -1U | wc -l

avoids aliases in your shell, doesn't sort the output, and lists 1 file-per-line (not strictly necessary when piping the output into wc).

The original question can be rephrased as "does the data structure of a directory store a count of the number of entries?", to which the answer is no. There isn't a more efficient way of counting files than readdir(2)/getdents(2).

查看更多
登录 后发表回答