3

Is there a reason why

find . -mindepth 1 -maxdepth 1 | wc -l

is suggested against

ls -1 | wc -l

(or vice-versa ?)

to count the total number of files/directories inside a folder

Notes:

  1. This question is more concerned with just counting stuff.
  2. There are no files with leading .
  3. There may be non-standard files with say a \n in it.
sjsam
  • 20,774
  • 4
  • 49
  • 94
  • Both will fail against filenames with newlines..as far as counting is concerned i don't see any difference, both will fail..Where did you find the recommendation? – heemayl May 10 '16 at 03:34
  • Do you need to account for non-standard file-names, including ones with `\n` (or `\r`) and other Control-Chars etc embedded? In that case search for `find . -print0` solutions, experiment and then post a new Q. If you don't need a completely bullet-proof solution, either version about seems usable. Good luck. – shellter May 10 '16 at 03:34
  • Do you need to count `.exrc` sort of files (leading `.` char)? Then you need to add that to the cmd. Good luck. – shellter May 10 '16 at 03:35
  • @shellter. I am not worried about leading `.` but there may be non-standard files – sjsam May 10 '16 at 03:41

2 Answers2

4

The first command...

find . -mindepth 1 -maxdepth 1 | wc -l

...will list files and directories that start with ., while your ls command will not. The equivalent ls command would be:

ls -A | wc -l

Both will give you the same answers. As folks pointed out in the comments, both of these will give you wrong answers if there are entries that contained embedded newlines, because the above commands are simply counting the number of lines of output.

Here's one way to count the number of files that is independent of filename quirks:

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0i echo | wc -l

This passes the filenames to xargs with a NUL terminator, rather than relying on newlines, and then xargs simply prints a blank line for each file, and we count the number of lines of output from xargs.

larsks
  • 228,688
  • 37
  • 348
  • 338
  • 1
    Or see the second answer to [this question](http://stackoverflow.com/questions/11307257/is-there-a-bash-command-which-counts-files). – larsks May 10 '16 at 03:47
  • As I mentioned in the question there are no files with leading `.` but there are non-standard files and thanks for the solution. – sjsam May 10 '16 at 03:56
  • did you mean `ls -a | wc -l` ? `-A` option says `do not list implied . and ..` – Sundeep May 10 '16 at 04:24
2

The reason find(1) is preferred to ls(1) is that

  • ls defaults to sorting the list of files
  • find has no sorting capability

Sorting can be extremely memory consuming for large data sets. So even though you can use ls -f or ls -U to disable sorting, I find that using find is safer because I know that the directory listing won't be sorted, no matter what options are passed to it.

In any case, telling the command to print less about each file can help in performance and correctness. Performance because the command can avoid the stat(2) call and correctness because if you e.g. only print the inode, you'll be certain that the name of the file won't affect the output (e.g. line breaks, carriage returns or other odd characters.)

mogsie
  • 3,847
  • 25
  • 25