2

I have some binaries and some .c extension files in my directory.

Here the output using ls

arrays.c basic0 basic0.c fromfb fromfb.c oute oute.c segmen.c simp simp.c

Here i want to filter binary files only , so I use

ls |grep -v .c

This command list all files, Then using grep I get files, except those file not ending with .c

What I expect is

basic0
fromfb
oute
simp

But What i got

fromfb
oute
simp

basic0 binary file missing. What is the problem with this?

3 Answers3

10

As per man grep

The period . matches any single character.

thus grep .c match any character followed by c

You might be looking for grep -v \.c or better grep -v '\.c$'

where

  • \. escape special meaning of .
  • c
  • $ end of line (when piped to ls output one file name par line)

as suggested by wildcard, you can also use grep -vF .c The -F flag tells grep to use arg as simple string, not regular expression.

SQB
  • 113
Archemar
  • 31,554
1

You need to escape the dot sign with "\.". Try with ls | grep -v "\.c$". Executing grep -v .c means any record that does not contain the charater c preceded by another character

1

man

man grep tells us that

The period . matches any single character.

This means that .c matches any single character followed by a c. Since you haven't anchored your expression, this matches any string that contains any character followed by a c.

Let's test that. What if we don't use the -v flag?

test

Let's see. First, we set up a test

~ $ mkdir test
~ $ cd test
~/test $ touch arrays.c
~/test $ touch basic0
~/test $ touch basic0.c
~/test $ touch fromfb
~/test $ touch fromfb.c
~/test $ touch oute
~/test $ touch oute.c
~/test $ touch segmen.c
~/test $ touch simp
~/test $ touch simp.c
~/test $ ls
arrays.c  basic0.c  fromfb.c  oute.c    simp
basic0    fromfb    oute      segmen.c  simp.c

Then we test ls | grep .c:

~/test $ ls|grep .c
arrays.c
basic0
basic0.c
fromfb.c
oute.c
segmen.c
simp.c

As you can see, not only do the intended C sources match, but the binary file basic0 matches as well. The i is matched by the . and the c is matched by (no surprise here) the c.

solution

You want to match C sources to exclude them. These files end with .c, so we tell grep to match those.

~/test $ ls|grep "\.c$"
arrays.c
basic0.c
fromfb.c
oute.c
segmen.c
simp.c

We've done two things here. First, we've escaped the dot, to make it a literal dot instead of "any single character". But this would still match a file called foo.c.bar which may or may not be your goal.
Assuming it's not, we've also anchored the c to be the last character. Now you're matching the strings that end with a dot and a c.

Reapplying -v is left as an exercise for the reader.

SQB
  • 113