Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My task was to print the number of files in the current directory without using ls and wc commands.

I had typed the following lines in the script:

find . -maxdepth 1 -type f \( ! -iname ".*" \) > list3
grep .* -c list3 > /dev/tty

The output is:


while according to my understanding it should only be: 22

Why doesn't that work?

share|improve this question

Why grep isn't working correctly

It doesn't work because you need to tell grep that .* is the actual pattern you're looking for.

grep '.*' -c list3

If you don't use the single quotes, your shell will expand .* to the names of every file in your directory. This is called Filename Expansion. For example a.txt b.txt, so grep will see:

grep a.txt b.txt -c list3

Since single quotes prevent expansion from happening, this is the way to go here.

Where your grep command is wrong:

By the way, you're going the wrong direction with the pattern here. The period . in a regular expression matches any character, and not the literal dot. See the man page for more info. So your regex currently says: "find any character and then a sequence of any character". Quite redundant.

If you actually mean to match:

[dot] [anything else]

… you need to escape the dot:


Where your find command could be improved:

I don't know what you mean to get rid of by

\( ! -iname ".*" \)

Your find command will prefix any file with the dot for the current working directory, thus you won't remove anything here. You could have just run:

find . -maxdepth 1 -type f
share|improve this answer

To address the original problem, counting files without ls and wc:

Pure shell syntax:

for i in *; do
    [ -f "${i}" ] && files=$((files+1))
echo ${files}

To add hidden files to the count, just change the globbing settings prior to the for loop.

Alternatively: fun with find and shell expansion:

echo $(($(find -maxdepth 1 -type f -printf '+1')))
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.