0

I am trying to create an egrep command to grep the number of lines containing a specific text from a text-file but seem to have an error somewhere.

The text-file contains several thousand lines and has the expression Lastname in several lines. Problem is, there are also expressions like xLastname or abcLastname in there which I DON'T want to grab. So the definition of the RegExpression should look like this:

EITHER there is no text at all in the line before Lastname appears OR there is text in the line BUT a space has to be between the random text and Lastname

I tried with ((.+\ )?|(^.))Lastname and ((.+\ )?|[^.])Lastname but it always results in the egrep command finding expressions like abcLastname.

Where is my mistake? The first part (.+\ ) ("If there is text, there HAS to be a space afterwards") seems to work fine but the second part ("OR there is no text at all") does not seem to work.

Isn't there a special character that I can use to simply check if whatever comes after it is the FIRST expression/character in the line? I cannot find that information online unfortunately.

Thanks to all of you in advance for your help

3
  • 5
    It's hard to say for sure without seeing some examples, but possibly what you want are word boundaries e.g. grep -E '\bLastname\b' Commented Jun 29, 2018 at 17:06
  • 2
    Or simply grep -w Lastname (-w means: "Select only those lines containing matches that form whole words.").
    – PerlDuck
    Commented Jun 29, 2018 at 17:27
  • I realized it now after over 3 hours with: ((.+\ )|(\ )|^)Lastname and it seems to finally work. But thanks a lot for your effort !
    – Donzo
    Commented Jun 29, 2018 at 18:47

1 Answer 1

1

First of all, you don't need to escape spaces, and you don't need to put parens inside an OR expression. So the regex from your comment simplifies to (.+ | |^)Lastname.

Now, the space is the important part, so it further simplifies to ( |^)Lastname, which is practically equivalent to \bLastname, where \b is a word boundary.

To prevent matches like LastnameABC, put another word boundary at the end: \bLastname\b. Or you could use grep option -w, which matches only whole words. These are equivalent:

grep -E '\bLastname\b'
grep -w Lastname

Credit to steeldriver and PerlDuck for suggesting these in the comments

The main problem with the regexes in your question is that the first group (.+ )? is optional because of the question mark. So ((.+ )?|^.) simplifies to (|^.). Now because the first part of the OR is null, the whole thing is effectively null. So (|^.)Lastname simplifies to just Lastname.

You must log in to answer this question.

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