Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to grep to include an optional word?

Tags:

I use the following grep query to find the occurrences of functions in a VB source file.

    grep -nri "^\s*\(public\|private\|protected\)\s*\(sub\|function\)" formName.frm

This matches -

    Private Sub Form_Unload(Cancel As Integer)
    Private Sub lbSelect_Click()
    ...

However, it misses out on functions like -

   Private Static Sub SaveCustomer()

because of the additional word "Static" in there. How to account for this "optional" word in the grep query?

like image 226
CodeBlue Avatar asked Apr 13 '12 14:04

CodeBlue


People also ask

How do you make a word optional in regex?

The '?' after the '(administratively )' capture group, basically tells the regex that the previous group/character is optional.

What does \b mean in grep?

The ' \ ' character, when followed by certain ordinary characters, takes a special meaning: ' \b ' Match the empty string at the edge of a word. ' \B ' Match the empty string provided it's not at the edge of a word.

Can I use regex in grep?

GNU grep supports three regular expression syntaxes, Basic, Extended, and Perl-compatible. In its simplest form, when no regular expression type is given, grep interpret search patterns as basic regular expressions. To interpret the pattern as an extended regular expression, use the -E ( or --extended-regexp ) option.

Can you use wildcards with grep?

The wildcard * (asterisk) can be a substitute for any number of letters, numbers, or characters. Note that the asterisk (*) works differently in grep. In grep the asterisk only matches multiples of the preceding character. The wildcard * can be a substitute for any number of letters, numbers, or characters.


2 Answers

You can use a \? to make something optional:

grep -nri "^\s*\(public\|private\|protected\)\s*\(static\)\?\s*\(sub\|function\)" formName.frm

In this case, the preceding group, which contains the string "static", is optional (i.e. may occur 0 or 1 times).

like image 183
FatalError Avatar answered Nov 14 '22 23:11

FatalError


When using grep, cardinality wise :

* : 0 or many
+ : 1 or many
? : 0 or 1 <--- this is what you need.

Given the following example (where the very word stands for your static) :

I am well
I was well
You are well
You were well
I am very well
He is well
He was well
She is well
She was well
She was very well

If we only want

I am well
I was well
You are well
You were well
I am very well

we'll use the '?' (also notice the careful placement of the space after 'very ' to mention that we'll want the 'very' word zero or one time :

egrep "(I|You) (am|was|are|were) (very )?well" file.txt

As you guessed it, I am inviting you to use egrep instead of grep (you can try grep -E, for Extended Regular Expressions).

like image 37
Skippy Fastol Avatar answered Nov 14 '22 22:11

Skippy Fastol