Friday, July 18, 2008

How to count number of files in a directory

Now that I am back from vacation, I had to take care of some chores, like uploading the pictures taken with my digital camera.

I stepped out during the long upload process (400+ pictures). When I returned, it was already done. To just make sure all pictures are now on the server, I wanted to count the number of files in the targetdir directory.

$ ls -1 targetdir | wc -l
454

The above command reads ls dash one piped to wc dash letter l.

Note that if you had used ls dash letter l instead, the count is one greater than the actual number of files. This is because ls dash letter l outputs an extra total line:

$ ls -1 targetdir 
total 529436
-rw-r--r-- 1 peter peter  1510976 Jul 13  2008 DSCN1001.jpg
....

The above method will count symbolic links as well as subdirectories in targetdir (but not recursively into subdirectories).

If you want to exclude subdirectories, you need a heavier duty tool than ls.

$ find targetdir -maxdepth 1 -type f | wc -l

-type f ensures that the find command only returns regular files for counting (no subdirectories).

By default, the find command traverses into subdirectories for searching. -maxdepth 1 prevents find from traversing into subdirectories. If you do want to count files in the subdirectories, just remove -maxdepth 1 from the command line.

Note that the find command does NOT classify a symbolic link as a regular file. Therefore, the above find -type f command does not return symbolic links. As a result, the final count excludes all symbolic links.

To include symbolic links, add the -follow option to find.

$ find targetdir -follow  -maxdepth 1 -type f | wc -l 

32 comments:

  1. Great howto. Helps alot to newcomers like me ;) Cheers!

    ReplyDelete
  2. Just so you know, your ads are against Google's TOS. The banner ad above comments section is cut and it isn't displaying Ads by Google tag on the ad.

    Thanks for the info btw, nice site.

    ReplyDelete
  3. Excellent! This was exactly what I had been looking for and more!

    ReplyDelete
  4. If you want to find, let's say, all the php files within a directory_tree, you can try the following:
    ls -R -l directory_name | grep .php | wc -l

    Hope this helps.

    ReplyDelete
  5. I wanted to know how many files each folder contained so I used this.

    for i in `ls -al |grep '^d'|awk '{print $9}'|grep -v '\.$'`; do c=`find $i|wc -l`; echo "$c $i"; done;

    ReplyDelete
  6. You can also use:

    for FOLDER in `find ./ -type d -mindepth 1 -maxdepth 1`; do echo $FOLDER; find $FOLDER -type f | wc -l; done

    ReplyDelete
  7. find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.

    ReplyDelete
  8. Nice, i'm newbie with Linux, this command really help to count folder at target dir :D

    ReplyDelete
  9. Thanks for your help dear.

    ReplyDelete
  10. Thx for this post. I didn't remember which program counts. :D


    Ehmmm... But one thing: It's probably more efficient if you use
    (a 1 (one) instead of a lower case "L" as parameter since it produces less output which might help to improve performance in a directory with very very many files or on a pc which is really slow.)
    $ ls -1 | wc -l

    ReplyDelete
  11. Ohh... I did a mistake. -.- I should buy some glasses...... Didn't see the 1 the first time... I thought this is a lower case "L".

    Sorry for this.

    ReplyDelete
  12. Both of the for/do loop options fail on directories with spaces in them, how would one fix that (other than not using spaces in directories)?

    ReplyDelete
  13. Or (only count files, shorter):

    for i in `ls -1b`; do c=`find $i -type f |wc -l`; echo "$c $i"; done;

    ReplyDelete
  14. You do not need to use the long listing with ls to do a count. If you pipe the output of ls it will list the files one line at a time. It is the equivalent of doing ls -1 (thats a number 1)

    For example, try 'ls | cat'

    Its probably safer to explicitly use -1, as there may be some obscure versions of ls out there that behave differently.

    ReplyDelete
  15. ls -l | grep ^- | wc -l
    ls -l | grep ^d | wc -l
    ls -l | grep ^l | wc -l

    ReplyDelete
  16. is there any way by which i can count the number of files in the current directory without using ls and wc commands ?

    ReplyDelete
  17. Good post! Thanks

    ReplyDelete
  18. To view only regular files, no (dir,symlink,exec):

    ls -F | sed '/[/@*]$/d'

    iPenguin

    ReplyDelete
  19. ls -1 doesn't count hidden files, but when using ls -1h instead counts two more: . and ..

    ReplyDelete
  20. is there no way without enumerating the directory? using some filesystem metadata or somethin.

    ReplyDelete
  21. Awesome post...Thanks very much..

    ReplyDelete
  22. ls and find require read permission to the directory contents. "stat -f%l" (BSD unix) does not. I think it's "stat -c%h" on linux.

    ReplyDelete
  23. I prefer the stat solution

    ReplyDelete
  24. Nice post, this prefer to my problem

    ReplyDelete
  25. You should never use ls for counting files since it will take ages if you got a directory with several million files while find will work much much faster for counting.

    ReplyDelete