The simple, correct, straightforward answer is @louis-matthijssen one. ls -1 handling of newline characters make, in this case, sensible to parse ls output. The marked one is wrong for the use of -R flag.
–
RmanoApr 24 '14 at 16:25

6 Answers
6

Why the -R? Why doing a full stat when you just need the filename? Why not ls -1 *.jpg| wc -l? (ok, not working if you have filenames with newlines in it. In that case you deserve it ;-) ...)
–
RmanoApr 24 '14 at 16:14

2

...and the question was "counting the number of files in a directory". Moreover, this will list recursively all content of subdirectories which name end in .jpg, not files in subdirectories ending in .jpg. Have you ever tested it?
–
RmanoApr 24 '14 at 16:28

1

The question says "files in a specific directory", which implies that subdirectory recursion is not wanted.
–
David RicherbyApr 24 '14 at 16:58

1

This also fails if there are too many files in the directory (because *.jpg is expanded by the shell, not by ls) and if there are files whose names begin with hyphens.
–
David RicherbyApr 24 '14 at 18:41

2

@DavidRicherby This actually works okay with files whose names start with hyphens, except when /path/to/dir is the empty string or when it itself is a relative path beginning with a hyphen. ls does replace some "weird" characters in filenames with a ? though, which could be a problem in other contexts (or if the extension itself contains one of those characters... which seems unlikely). The more important (but fixable) problem is, as l0b0 points out, the pattern here doesn't match filenames beginning with ..
–
Eliah KaganSep 21 '14 at 11:43

Unfortunately this benign problem is difficult to solve in a way which supports all file names and is portable. This is safe (it handles hidden files, paths containing spaces, dashes and even newlines) and POSIX compatible:

you do not need the "-exec printf ..." , just find | wc -l . I do not think you want the -c option
–
bodhi.zazenApr 24 '14 at 15:54

2

No, you really do need it. find | wc -c counts the number of characters in the file listing, and find | wc -l gives you the wrong result for file names containing newlines.
–
l0b0Apr 24 '14 at 15:56

1

+1 for the "don't parse ls" link. It's a best practice, and vital if you're going to act on the output. A simple ls is probably pretty safe, but I like encouraging good practices. :)
–
K. Darien FreeheartApr 24 '14 at 16:01

use ls without piping to grep and shorten your answer. It has been posted at least twice now.
–
bodhi.zazenApr 24 '14 at 16:19

@bodhi.zazen ls /directory/*.mp4 causes the shell to expand the glob and execute something like ls /directory/file1.mp4 /directory/file2.mp4 ... This will fail if the directory contains more mp4 files than can be passed as arguments to ls.
–
David RicherbyApr 24 '14 at 17:03

@DavidRicherby - it is not my ls command , I use find ;)
–
bodhi.zazenApr 24 '14 at 17:14

Not sure why this was downvoted, it works
–
bodhi.zazenApr 24 '14 at 16:13

Yes. Even for files with newlines embedded --- ls -1 output a question mark in that case, which is a sane behavior... +1 from me. A lot of people comment without testing.
–
RmanoApr 24 '14 at 16:21

Since *.mp4 is expanded by the shell, not ls, this will fail if there are so many .mp4 files in the directory that the list of them can't be passed to ls as arguments.
–
David RicherbyApr 24 '14 at 17:06

@Rmana Test it in a directory containing a file called --.mp4
–
David RicherbyApr 24 '14 at 19:33

@DavidRicherby yes, you are right. -- will solve the second case; the former will rise an error message (you need a lot of files!) and another nice question here. Corner cases, but worth noticing, yes.
–
RmanoApr 25 '14 at 12:59

This lists the contents of your directory, including hidden files, with one file per line. It passes the result to grep which will only show items containing the .mp4 extension. This list is then passed to "word count" to count the lines.

The result will output the number of lines that match, which will correspond to the number of .mp4 files you have in that directory.

While this also works, just use ls without the pipe.
–
bodhi.zazenApr 24 '14 at 16:14

This does not work. It gives the wrong answer if the directory contains a file called ".mp45", for example. It also fails if there are files with newlines in their names. By the way, "grep -c" outputs just the number of matching lines.
–
David RicherbyApr 24 '14 at 16:53