6 Answers
6

You want ls | grep '\.c$' if you want to find all files that end in .c.

grep matches any substring by default, not the whole string, so you don't need to write something that matches the beginning of the filename. If you did want to write that, it would be .* in a regular expression. . indicates "any character except for a line ending", and * indicates "any number (zero or more) of the previous expression".

Because . has a special meaning in a regular expression, if you want to match a literal ., you need to escape it with \. Because \ has a special meaning in the shell, you need to quote the regular expression with single quotes (').

To ensure that you match only at the end of the filename, you use $, which matches the end of the line.

This guy didn't deserve to get downvoted, it is what the command ls | grep *.c is doing if there are more than one file in the current directory, due to bash expansion, like I further explained in my answer.
–
KurzedMetalJan 16 '13 at 18:14

grep "*.c" is going to look LITERALLY for string "*.c", that is, string "asterisk dot c" without expanding it to mean "all the files with .c extension", which is why it is not finding anything in output of "ls":

# touch b.c

# ls -1 | grep "*.c"

result is empty.

If you want expansion, you should use egrep (extended grep) which does regular expressions. But here they're a tad different: