Recursively counting files in a Linux directory
This should work:
find DIR_NAME -type f | wc -l
Explanation:
-
-type f
to include only files. -
|
(and not¦
) redirectsfind
command's standard output towc
command's standard input. -
wc
(short for word count) counts newlines, words and bytes on its input (docs). -
-l
to count just newlines.
Notes:
- Replace
DIR_NAME
with.
to execute the command in the current folder. - You can also remove the
-type f
to include directories (and symlinks) in the count. - It's possible this command will overcount if filenames can contain newline characters.
Explanation of why your example does not work:
In the command you showed, you do not use the "Pipe" (|
) to kind-of connect two commands, but the broken bar (¦
) which the shell does not recognize as a command or something similar. That's why you get that error message.
For the current directory:
find -type f | wc -l
If you want a breakdown of how many files are in each dir under your current dir:
for i in */ .*/ ; do
echo -n $i": " ;
(find "$i" -type f | wc -l) ;
done
That can go all on one line, of course. The parenthesis clarify whose output wc -l
is supposed to be watching (find $i -type f
in this case).
On my computer, rsync
is a little bit faster than find | wc -l
in the accepted answer:
$ rsync --stats --dry-run -ax /path/to/dir /tmp
Number of files: 173076
Number of files transferred: 150481
Total file size: 8414946241 bytes
Total transferred file size: 8414932602 bytes
The second line has the number of files, 150,481 in the above example. As a bonus you get the total size as well (in bytes).
Remarks:
- the first line is a count of files, directories, symlinks, etc all together, that's why it is bigger than the second line.
- the
--dry-run
(or-n
for short) option is important to not actually transfer the files! - I used the
-x
option to "don't cross filesystem boundaries", which means if you execute it for/
and you have external hard disks attached, it will only count the files on the root partition.