3

I'm stumped writing a regex to put into grep to match all lines which contain foo_bar and all other lines to don't contain foo_.* (Excepting foo_bar which should still match).

So given:

foo_bar Line 1
foo_baz Line 2
Line 3
foo_biz Line 4

I'd want Lines 1 and 3 returned.

Note I can't just match not foo_baz and not foo_biz as baz and biz can be many, many things. It needs to be foo_.*

Matt Fellows
  • 6,512
  • 4
  • 35
  • 57

3 Answers3

3

You need to combine a postivie match and a negative match So positive Match 1 for foo_bar

foo_bar

Then negative match 2 for all this is not containing foo_ using Stack overflow great explanation Regular expression to match a line that doesn't contain a word?

^((?!foo_.*).)*$

Combining both in an altnernative regexp

(foo_bar|^((?!foo_.*).)*$)

Now let's try::

    $ cat <<EOF | perl -ane ' /(foo_bar|^((?!foo_.*).)*$)/ && print $_'
    > foo_bar 1
    > fee_foo
    > foo bar
    > foo_buz RT
    > fo_foo 1 
    > fo_ foo_bar
    > EOF

gives

foo_bar 1
fee_foo
foo bar
fo_foo 1 
fo_ foo_bar
Community
  • 1
  • 1
user1458574
  • 151
  • 1
  • 2
3

Under OS X I executed the following command on your input :

$ grep -P -v '^foo_(?!bar)' test.txt 
foo_bar Line 1
Line 3

Please note that :

-P, --perl-regexp
       Interpret PATTERN as a Perl regular expression.
-v, --invert-match
       Invert the sense of matching, to select non-matching lines.
Ludovic Kuty
  • 4,868
  • 3
  • 28
  • 42
0

With sed:

sed -n '/foo_bar/p;/foo_/!p' input

this tells the sed not to print by default (-n) and print when either foo_bar matches or foo_ does not match.

perreal
  • 94,503
  • 21
  • 155
  • 181