1

I have a folder and I want count all regular files in it, and for this I use this bash command:

find pathfolder -type f  2> err.txt | wc -l

In the folder there are 3 empty text files and a subfolder with inside it other text files. For this reason I should get 3 as a result, but I get 6 and I don't understand why. Maybe there is some options that I did not set.

If I remove the subfolder I get 4 as result

tux3
  • 7,171
  • 6
  • 39
  • 51
mario razzu
  • 333
  • 1
  • 5
  • 12

2 Answers2

2

To grab all the files and directories in current directory without dot files:

shopt -u dotglob
all=(*)

To grab only directories:

dirs=(*/)

To count only non-dot files in current directory:

echo $(( ${#all[@]} - ${#dirs[@]} ))

To do this with find use:

find . -type f -maxdepth 1 ! -name '.*' -exec printf '%.0s.\n' {} + | wc -l
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

Below solutions ignore the filenames starting with dot.

To count the files in pathfolder only:

find pathfolder -maxdepth 1 -type f -not -path '*/\.*' | wc -l

To count the files in ALL child directories of pathfolder:

find pathfolder -mindepth 2 -maxdepth 2 -type f -not -path '*/\.*' | wc -l

UPDATE: Converting comments into an answer

Based on the suggestions received from anubhava, by creating a dummy file using the command touch $'foo\nbar', the wc -l counts this filename twice, like in below example:

$> touch $'foo\nbar'
$> find . -type f
./foo?bar
$> find . -type f | wc -l
2

To avoid this, get rid of the newlines before calling wc (anubhava's solution):

$> find . -type f -exec printf '%.0sbla\n' {} +
bla
$> find . -type f -exec printf '%.0sbla\n' {} + | wc -l
1

or avoid calling wc at all:

$> find . -type f -exec sh -c 'i=0; for f; do ((i++)); done; echo $i' sh {} +
1
Community
  • 1
  • 1
Eugeniu Rosca
  • 5,177
  • 16
  • 45
  • 1
    This will give wrong count if a filename has newline character – anubhava Jun 11 '15 at 18:21
  • anubhava: Honestly, I never saw such filenames :) @mario-razzu: to count in ALL child directories of `pathfolder` you could use: `find pathfolder -type f -mindepth 2 -maxdepth 2 -not -path '*/\.*'`. To cound only in `pathfolder`: `find pathfolder -type f -maxdepth 1 -not -path '*/\.*'` – Eugeniu Rosca Jun 11 '15 at 18:25
  • I get only the files in the subfolder – mario razzu Jun 11 '15 at 18:29
  • 1
    @chatraed: Filenames with space and newlines are not very common but very much possible. – anubhava Jun 11 '15 at 18:42
  • @anubhava: you suggest there could be a space or \n between the slash and the dot and the `-not path` pattern `'*/\.*` is not good? – Eugeniu Rosca Jun 11 '15 at 18:44
  • 1
    No but if a filename has newline then `wc -l` will count that file as 2 instead of 1 – anubhava Jun 11 '15 at 18:48
  • 1
    @anubhava: created some files containing spaces and `\n` and observed no difference in the counting results. Anyways, I vote for your answer. – Eugeniu Rosca Jun 11 '15 at 18:56
  • 1
    Thanks. In an empty directory create a file using `touch $'foo\nbar'` command and then run your first `find` command. It will print `2` instead of `1`. – anubhava Jun 11 '15 at 18:59
  • Ok it works. I edited it in this way: I use only mindepth 1 and in this way find command search in all subfolder and in the main folder. The only thing not clear to me is "-not -path '*/\.*' ". – mario razzu Jun 11 '15 at 19:50
  • @mario razzu: You can use `-not -path '*/\.*'` or `! -name '.*'` (anubhava's version). It's the same thing to ignore the filenames starting with dot. – Eugeniu Rosca Jun 11 '15 at 19:52
  • ok amazing! I tried to remove that(for testing) and it counts only ".DS_Store" file and not the "." and "..". is it special file? – mario razzu Jun 11 '15 at 20:12
  • See [this](http://stackoverflow.com/questions/18865957/are-the-dot-and-dot-dot-files-in-unix-and-linux-real-files) . – Eugeniu Rosca Jun 11 '15 at 20:16