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

  • 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' – steeldriver Jun 29 '18 at 17:06
  • 2
    Or simply grep -w Lastname (-w means: "Select only those lines containing matches that form whole words."). – PerlDuck Jun 29 '18 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 Jun 29 '18 at 18:47
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.

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.