0

In this case discussed: find (GNU findutils) 4.5.11 grep (GNU grep) 2.20

Let's say I have a directory that contains a bunch of files. I want to find the files named jtobdops02.key and jtobdops.02.cer.

find . -regextype posix-extended -regex ".*jtobdops02\.(key|cer)"

Gives:

./certs/jtobdops02.key

./certs/jtobdops02.cer

find . -type f | grep -E '.*jtobdops02.*(key|cer)'

Also gives as expected:

./certs/jtobdops02.key

./certs/jtobdops02.cer

Yet

find . -type f | grep -E '*jtobdops02.*(key|cer)'

Gives this:

./certs/jtobdops02.key

./certs/jtobdops02.cer

The man for find states:

This is a match on the whole path, not a search.

The man for grep states:

grep, egrep, fgrep - print lines matching a pattern

If they both do matching, not search, why does the latter grep still work? Also in the latter case there is no preceding sub expression for grep to match, so what does the * match in this case? The colored(bold) output shows no difference, so I assume it does nothing. Shouldn't it give error in this case?

Which one of those is idiosyncrasy and which one of those is a general practice across other tools and languages?

  • 2
    The first * is meaningless so the expression is equivalent to 'jtobdops02.*(key|cer)' – don_crissti Mar 18 '16 at 0:57
  • 1
    Yes, it can be argued that a regular expression beginning with * should result in an error.  Maybe they thought it was more user-friendly just to ignore the *. – G-Man Mar 18 '16 at 4:08
0

An extended regular expression starting with an * will produce an undefined result, according to the POSIX standard.

This is with grep on OpenBSD 6.4:

$ grep -E '*hello'
grep: repetition-operator operand invalid

GNU grep seems to ignore the * altogether:

$ printf 'hello\n' | ggrep -E '*hello'
hello

According to the same standard, if using basic regular expressions (grep without -E), an * at the start of an expression or subexpression inside \(...\) (or right after an initial ^) is to be interpreted as a literal *.

  • 1
    ggrep's '*hello' is probably interpreted as <nothing>*hello (any number of nothing). echo xfoo | ggrep -E '^*foo' (or '^?foo') seems to match but with zero-width somewhere. Neither echo xfoofoo | ggrep -E '(^*foo)\1' nor echo xfooxfoo | ggrep -E '(^*foo)\1?' match. Seems buggy. – Stéphane Chazelas Dec 12 '18 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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