68

I want to count the total number of files in particular directory that ends with ".mp4" extension.

I am getting following command:

ls -F |grep -v / | wc -l

It count all the files in particular directory, but I want the count of files that end with .mp4 extension.

Is there any Ubuntu command for that?

1
  • 2
    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.
    – Rmano
    Apr 24, 2014 at 16:25

10 Answers 10

64

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:

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

If you don't want it to be recursive, simply add -maxdepth 1.

You shouldn't parse ls output.

Test:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

Compare with the accepted answer:

$ ls -lR ./*.mp4 | wc -l
3

Or other suggestions:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3
6
  • 2
    Although this answer is correct and robust, you can use -printf x instead of -exec printf x \;. That is: find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c There's no need to -exec the external printf command, which if there are many files will be very slow, because find has to fork(2) off a copy of itself and then execve(2) /usr/bin/printf. With -exec printf x \;, that must be done once for each file. Oct 10, 2017 at 17:39
  • -printf is not supported in POSIX find, which is why I didn't use it.
    – l0b0
    Oct 11, 2017 at 6:49
  • 1
    Neither are -mindepth and -maxdepth, which you used. Oct 11, 2017 at 10:34
  • Good point, I hadn't picked up on that!
    – l0b0
    Oct 11, 2017 at 18:27
  • 2
    fyi, this doesn't work on macOS, "-printf: unknown primary or operator"
    – Jemshit
    Jun 9, 2022 at 7:46
37

Here you can do this way

ls -lR /path/to/dir/*.jpg | wc -l

This gives you count

8
  • 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 ;-) ...)
    – Rmano
    Apr 24, 2014 at 16:14
  • 3
    ...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?
    – Rmano
    Apr 24, 2014 at 16:28
  • 1
    The question says "files in a specific directory", which implies that subdirectory recursion is not wanted. Apr 24, 2014 at 16:58
  • 2
    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. Apr 24, 2014 at 18:41
  • 2
    @DavidRicherby This skips names that start with .. But it actually works okay with hyphens in names, except when /path/to/dir is the empty string or a relative path beginning with a hyphen. But I was wrong before to have said ls replaces characters with ?. That happens when stdout is a terminal, but here the output is a pipe so ls sends all characters from filenames to wc. That makes this answer wrong without the -q or -b flag to change that behavior, because filenames can contain newlines. l0b0's answer is free of these problems. Oct 10, 2017 at 17:49
29

This one finds, sorts, and lists all files by extension in order:

find . -type f | sed 's/.*\.//' | sort | uniq -c
4
  • 3
    Excellent! I just would add a | sort -rn at the end and maybe a -mindepth 1 if just current dir. May 24, 2017 at 23:41
  • And maybe pipe to head -n to get the top n.
    – Raman
    Jul 10, 2017 at 0:55
  • I had to add another | sort and added -maxdepth 1 for myself Jun 7, 2021 at 17:49
  • This is great! To also count filename without extension, I ended up with find . -type f -printf '%f\n' | sed --regexp-extended 's/(^.*\.)|(^[^.]*$)//' | sort | uniq --count | sort --numeric-sort --reverse May 16, 2022 at 12:52
15

I think it's very simple as following commands.

$ find . -name "*.mp4" | wc -l
8

or

$ find . | grep -i ".mp4$" | wc -l
8

I think that above commands calculate count of files and directories names *.mp4

so I suggest you use -type f option as find parameter as following.

$ find . -name "*.mp4" -type f | wc -l
8

In addition, ls -lR can be used as find .

0
4

You could use ls -1 *.mp4 | wc -l.

This will list all files ending on .mp4, printing each file on a new line (ls -1 *.mp4), pipe the output to wc which will count the number of new lines using the -l flag.

5
  • Not sure why this was downvoted, it works
    – Panther
    Apr 24, 2014 at 16:13
  • 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. Apr 24, 2014 at 17:06
  • @Rmana Test it in a directory containing a file called --.mp4 Apr 24, 2014 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.
    – Rmano
    Apr 25, 2014 at 12:59
  • 1
    @Rmano Without adding -q or -b, this does not tolerate newlines in filenames. If you run ls -1 *.mp4 from your terminal with no pipe, ls sees its stdout is a terminal and takes -q as implied, printing ?s. But that behavior goes away when the output is piped. ls -1 *.mp4 | wc -l overcounts if there are newlines. ls -1 *.mp4 | cat shows what wc "sees." (Similarly, -1 is implied when stdout isn't a terminal, so it's optional.) ls -1q -- *.mp4 | wc -l almost works, but not with zero .mp4 files. Oct 11, 2017 at 11:42
3

This should give you the list of file with .mp4

ls /path/to/directory | grep ".mp4$"

When combined with wc -l will give you count

ls /path/to/directory | grep ".mp4$" | wc -l

if you want search to include subdirectories

ls -lR /path/to/directory | grep ".mp4$" | wc -l
9
  • does not give a count
    – Panther
    Apr 24, 2014 at 16:15
  • gave it to me when used with wc -l
    – Back.Slash
    Apr 24, 2014 at 16:16
  • use ls without piping to grep and shorten your answer. It has been posted at least twice now.
    – Panther
    Apr 24, 2014 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. Apr 24, 2014 at 17:03
  • @DavidRicherby - it is not my ls command , I use find ;)
    – Panther
    Apr 24, 2014 at 17:14
2

Check How To Count The Files By Extension In Linux?, it gives a good answer and explanation, you can use the following command:

find . -type f | sed -n 's/..*\.//p' | sort | uniq -c
2

You can always just use a for loop, which I think has the advantage of not requiring you to remember the flags of several different commands.

For example:

a=0; for i in ./*.jpg; do a=$(expr  $a + 1); done; echo $a 
1

In bash, one cold resort to using arrays with glob:

$ files=( *.mp4  )
$ echo ${#files[@]}
30
1
ls | grep --count \.csv$

Replace (.csv with the extension you want)

Explanation: I think that a simple scheme is to fetch the list of files, and count the extension with grep. \. to match . and $ to match the extension at the end of line. It works because when the output of ls is piped, one file name is sent per line, which you can verify by running:

ls | cat
1
  • 1
    Note that instead of grep --count, you could also use grep -c. Jun 22, 2018 at 19:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .