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
  • 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
    Commented Mar 20, 2018 at 11:54

3 Answers 3

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
1
  • 1
    "early nighties" - Freudian slip? Commented Mar 20, 2018 at 20:57
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
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .