4

I'm using this script to save the number of files in a main folder, but it also counts the subfolders inside that main folder. nfiles=$(ls -1 /home/userA/mainfolder | wc -l) Any advice how I can modify it to only include files not folders?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Tak
  • 519
  • 4
  • 11
  • 23
  • 2
    `find . -maxdepth 1 -type f | wc -l` ([don't parse `ls`](http://mywiki.wooledge.org/ParsingLs))... – jasonwryan Mar 16 '15 at 02:50
  • @jasonwryan I tried this one `nfiles= find /home/userA/mainfolder -maxdepth 1 -type f | wc -l` but it says `bash: /home/userA/mainfolder: is a directory 0` – Tak Mar 16 '15 at 02:55
  • 1
    `nfiles=$(find . -maxdepth 1 -type f | wc -l) && echo "$nfiles"` – jasonwryan Mar 16 '15 at 03:25
  • @jasonwryan this includes hidden files as well, is it possible to only include visible files? Also please post it as an answer to accept it :) – Tak Mar 16 '15 at 03:27

2 Answers2

3

Don't use find for this.

Besides requiring non-portable GNU extensions to make it work, it also has to stat() every file for which it searches. ls, on the other hand, can simply list the current directory's dentries out -1 per line while -quoting all non-printables with a ? question mark (to include \newlines), and appending a / for each directory listing.

That way for a simple -count of non-dotfiles in the current directory you can just do:

ls -1pq | grep -c -v /

And the entire process is not only likely faster than find would be, it is also POSIXly done.

mikeserv
  • 57,448
  • 9
  • 113
  • 229
2

Rather than parsing ls, you can use find:

find . -maxdepth 1 -type f ! -name ".*" | wc -l

This will find all files (-type f) in the current directory (.) except those beginning with a . (! -name ".*") and pass the result to wc to count the lines.

To use it as a variable in your script:

nfiles=$(find . -maxdepth 1 -type f ! -name ".*" | wc -l)
terdon
  • 234,489
  • 66
  • 447
  • 667
jasonwryan
  • 71,734
  • 34
  • 193
  • 226
  • 1
    @mikeserv you should make that an answer. – jasonwryan Mar 16 '15 at 04:22
  • How, exactly, is this superior to "parsing `ls`"?  One of the big issues with parsing the output from `ls` is that filenames can contain newlines.  Well, won't `find … -print | wc -l` fail in exactly the same way as `ls | wc -l`?  Hint: see [this](http://unix.stackexchange.com/a/27498/80216) and [this](http://superuser.com/a/689326/354511). – G-Man Says 'Reinstate Monica' May 06 '15 at 03:53