LS or Find – How to Exclude . and ..

findwc

I have 35 files and directory in my home at the first level (without descending into subdirectories).
But the results are "faked" and report 36 because they include the . special directory.
How can I exclude the "."?

I have tried the switch -not -path but it doesn't work.

find . -not -path '*/\.*' -not -path /\. -maxdepth 1|wc -l
36
find $HOME -not -path '*/\.*'  -maxdepth 1|wc -l
36

Best Answer

find includes the directories from which it starts; exclude those from the output, without decoration, to get the result you’re after:

find . -maxdepth 1 ! -path . | wc -l
find "$HOME" -maxdepth 1 ! -path "$HOME" | wc -l

(as long as $HOME doesn’t contain any characters which would be interpreted as pattern characters, i.e. *, ?, []). You can also match against the . name only, by appending it (if necessary) to the path you’re interested in:

find . -maxdepth 1 ! -name . | wc -l
find "$HOME"/. -maxdepth 1 ! -name . | wc -l

To accurately count the files found by find, you should count something other than the file names (which can include newlines), e.g. if your find supports -printf:

find . -maxdepth 1 ! -name . -printf 1 | wc -c

or, with POSIX find, by using the // trick:

find .//. -maxdepth 1 ! -name . | grep -c //

.. isn’t a problem with find, it doesn’t include it unless you add it explicitly (find .. ...).

ls won’t show . and .. by default; if you want to see hidden files, but not . and .., use the -A option instead of -a. With GNU ls, you can ask it to quote special characters, which will allow you to accurately count files:

ls -q1A . | wc -l
Related Question