2

I'm trying to grep for possible matches to,

ex****e

So anything with ex at the start and e at the end with 4 characters inbetween, how could I do this?

  • 1
    please clarify if you are looking to match words or whole lines... in other words, adding sample input lines and expected output helps.. – Sundeep Mar 20 '18 at 11:54
11

The regular expression operator that matches a single character is .. That's similar to ? in shell wildcards. * itself matches any number of the preceding thing in regular expressions (for instance, a* matches any number (including 0) of as), and any number of characters in shell wildcards.

POSIXly, to find lines that match exactly on that:

grep -xE 'ex.{4}e'

Or:

grep -x ex....e

Or:

grep -x 'ex.\{4\}e'

The second of which being the most portable. grep '^ex....e$' would even work in the original implementation in Unix Version 4 (1973); however -x was added in Unix Version 7 (1979) and is universal nowadays so you can rely on that one.

Extended regular expressions were added in egrep in V7 as well but initially without the {x,y} interval operators. That operator was added as \{x,y\} for grep but often not in egrep as that would have broken backward compatibility. In the early nineties however, POSIX introduced the -E option of grep to merge in the egrep functionality into grep and requires it support {x,y} and egrep is now deprecated.

However, you still occasionally find some grep implementations that don't support -E or egrep ones that don't support {x,y} like the /bin/grep and /bin/egrep of Solaris (where you need to use /usr/xpg4/bin/grep instead).

Beware that some grep implementations are not multibyte aware and their . regexp operator may match on each byte of a multibyte character like the non-ASCII UTF-8 characters).

$ $ locale charmap
UTF-8
$ echo extrême | busybox grep -x ex....e 
$ echo extrême | gnu-grep -x ex....e
extrême
$ echo extrême | busybox grep -x ex.....e
extrême

As the ê character is made of two bytes in UTF-8, extrême is 7 characters, but 8 bytes:

$ printf %s extrême | wc -cm
      7       8
2

With the following regex :

^ex.{4}e$

Ex :

$ grep -E '^ex.{4}e$' <<< 'ex****e'

or

$ grep '^ex.\{4\}e$' <<< 'ex****e'

Output :

    ex****e
0

The basic pattern suggested by @stéphane-chazelas:

grep -xE 'ex.{4}e'  

will find any line consisting soley of 'e', 'x', any 4 chars, and 'e' and no white space due to the switch '-x' , equivalent to @gilles-quenot's suggestion of

grep -E ^ex.{4}e$

However, OP wanted "anything with ex at the start and e at the end with 4 characters inbetween", so that would include lines with non-matching content and matching content together. In order to get that, you would need the pattern,

    grep -E 'ex.{4}e'

Quotes to prevent shell bracket expansion.

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.