Shell UNIX : grep wild card

10,011

Solution 1

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.

Solution 2

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).”

Solution 3

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.

Share:
10,011
Victor
Author by

Victor

Updated on June 04, 2022

Comments

  • Victor
    Victor almost 2 years

    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 ?