Reputation: 243
I can't figure out why the wild character * is interpreted differently in the following examples with grep :
find . -type f -name \*
Results :
./tgt/etc/test_file.c
./tgt/etc/speleo/test_file.c
./tgt/etc/other_file.c
./src/file.c
I want to return from this command the files that match a pattern with eventually a wildcard *. But :
find . -type f -name \* | grep "tgt/etc/*" # this one works
find . -type f -name \* | grep tgt/etc/* # not this one
find . -type f -name \* | grep tgt/et*/s* # this one works
find . -type f -name \* | grep "tgt/et*/s*" # not this one
I'd like to have an implementation which works fine with both cases. What should I use ?
Upvotes: 3
Views: 11216
Reputation: 780688
The first argument to grep
is not a wildcard, it's a regular expression. In a regular expression, *
means to match any number of the character or expression that precedes it. So
grep "tgt/etc/*"
means to match tgt/etc
followed by zero or more /
characters. In a wildcard, *
means to match any number of any characters, the equivalent regular expression is .*
. For your purposes, the commands you want are:
find . -type f -name \* | grep "tgt/etc/"
find . -type f -name \* | grep "tgt/et.*/s"
Also, if you don't quote the argument, and it contains any *
characters, the shell will expand the argument as a filename wildcard before passing them as arguments to grep
. So when you write:
find . -type f -name \* | grep tgt/etc/*
the shell will expand this to
find . -type f -name \* | grep tgt/etc/file1 tgt/etc/file2 tgt/etc/file3
This will treat the tgt/etc/file1
as the regular expression to search for, and look for it inside the remaining files -- it will not process the input from the pipeline because it was given filename arguments.
Upvotes: 5
Reputation: 24812
it's because grep
uses regexps and no wildcards.
so basically, what you do is:
tgt/etc/*
checking zero or sereval /
tgt/et*/s*
checking zero or several t
and zero or several s
but thing is that when you do not put quotes around the regexp, the shell is expanding the *
as wildcards, which messes up the regexp grep sees.
Upvotes: 1
Reputation: 8774
The unquoted examples (without the "
) are expanded by the shell, before grep
ever sees them. That is just the way Unix shells work.
For the quoted ones, note that *
in a grep pattern means something different from what it means to the shell and to find
: It means “repeat the preceding character any number of times (including zero).”
Upvotes: 3