Q: grep 'foo' NOT followed by 'bar'

Q: grep 'foo' NOT followed by 'bar'

Post by Vincent Zoc » Wed, 07 Sep 1994 16:33:30



Hello,

I want to use some grep command to match lines that contain
some word and NOT followed by another.
Examples:
    [1]    ^foo$
    [2]    ^foobar$
    [3]    ^foo foobar$
    [4]    ^fooba$

I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
4 would match. (line 3 has a foo NOT followed by bar)

Question:
    How should I do this?
    I tried a few things but did not succeed. (I rtfm, the Unix FAQ
    and O'Reilly's Unix in a Nutshell I believe)
    This may not matter but I try to do this on AIX 3.2.5

Cheers,
Vincent Zocca

PS: I noteced that our nn is freaked up (21 hours no news and I am
    no longer sysadmin) so an email would help me quicker I believe.

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Cooper Ver » Wed, 07 Sep 1994 18:58:16


    VZ> I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3
    VZ> and 4 would match. (line 3 has a foo NOT followed by bar)

Negating a regular expression is tricky business.  For this relatively
easy example, you need something like:

egrep 'foo([^b]|b[^a]|ba[^r])' baz.txt  #Those parens need to be escaped, really

As you can see, the regexp will quickly get very complicated.  Here's
one for regular, not followed by expression:

egrep 'regular ([^e]|e[^x]|ex[^p]|exp[^r]|expr[^e]|expre[^s]|expres[^s]|express[^i]|expressi[^o]|expressio[^n])' baz.txt

(An elisp macro makes short work of it.  If you use emacs, let me
know)

--
                                                         =[ cooper ]=

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Bernhard Rossbo » Wed, 07 Sep 1994 19:26:12



:
:     VZ> I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3
:     VZ> and 4 would match. (line 3 has a foo NOT followed by bar)
:
: Negating a regular expression is tricky business.  For this relatively
: easy example, you need something like:
:
[example deleted]
: As you can see, the regexp will quickly get very complicated.  Here's
: one for regular, not followed by expression:
:
[...]

It's much easier to grep twice:

grep foo filename | grep -v foobar

Barny ;-{)

--
----

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Uwe Waldma » Wed, 07 Sep 1994 22:02:26




> I want to use some grep command to match lines that contain
> some word and NOT followed by another.
> Examples:
>     [1]    ^foo$
>     [2]    ^foobar$
>     [3]    ^foo foobar$
>     [4]    ^fooba$

> I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
> 4 would match. (line 3 has a foo NOT followed by bar)

It's difficult to do with egrep (see Cooper Vertz's article, Message-ID:

there is another way.  The basic idea is:

 - save a copy of the input line.
 - replace every 'foobar' by a space.
 - check whether there is any 'foo' left.
 - if so, print the saved line.

In sed that becomes:

sed -e '
h
s/foobar/ /g
/foo/ {
g
p

Quote:}

'

The perl equivalent:

perl -ne '
$save = $_;
s/foobar/ /g;
if (/foo/) {print $save;}
'

Quote:> PS: I noteced that our nn is freaked up (21 hours no news and I am
>     no longer sysadmin) so an email would help me quicker I believe.

[I'll send you an e-mail copy.]

--
Uwe Waldmann, Max-Planck-Institut fuer Informatik
Im Stadtwald, D-66123 Saarbruecken, Germany

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Charles Dayt » Thu, 08 Sep 1994 12:56:15






>> :
>> :     VZ> I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3
>> :     VZ> and 4 would match. (line 3 has a foo NOT followed by bar)
>> :
>> It's much easier to grep twice:
>> grep foo filename | grep -v foobar
>This *almost* does what the original poster asked for, but not quite.
>Note example [3] below from the original query: it is supposed to
>succeed, but it will fail in the above "grep twice" solution.
>>    [1]    ^foo$
>>    [2]    ^foobar$
>>    [3]    ^foo foobar$
>>    [4]    ^fooba$

>With the stipulation that [3] succeeds, the longer, more compilcated
>solution seems, unfortunately, to be the only way if you are
>restricting yourself to 'grep' (and 'egrep').  If you are willing to
>use 'awk' or 'perl', you might be able to come up with something a bit
>more "elegant".

I think that you can do this fairly easily

grep ^foo filename | grep -v ^foobar

Soren
--
Soren Dayton

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Lloyd Zusm » Thu, 08 Sep 1994 03:00:51





> :
> :     VZ> I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3
> :     VZ> and 4 would match. (line 3 has a foo NOT followed by bar)
> :
> : Negating a regular expression is tricky business.  For this relatively
> : easy example, you need something like:
> :
> [example deleted]
> : As you can see, the regexp will quickly get very complicated.  Here's
> : one for regular, not followed by expression:
> :
> [...]
> It's much easier to grep twice:
> grep foo filename | grep -v foobar

This *almost* does what the original poster asked for, but not quite.
Note example [3] below from the original query: it is supposed to
succeed, but it will fail in the above "grep twice" solution.

Quote:>I want to use some grep command to match lines that contain
>some word and NOT followed by another.
>Examples:
>    [1]    ^foo$
>    [2]    ^foobar$
>    [3]    ^foo foobar$
>    [4]    ^fooba$

>I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>4 would match. (line 3 has a foo NOT followed by bar)

With the stipulation that [3] succeeds, the longer, more compilcated
solution seems, unfortunately, to be the only way if you are
restricting yourself to 'grep' (and 'egrep').  If you are willing to
use 'awk' or 'perl', you might be able to come up with something a bit
more "elegant".

--
Lloyd Zusman            01234567 <-- The world famous Indent-o-Meter.

  To get my PGP public key automatically mailed to you, please send me email
  with the following string either as the subject or on a line by itself:
                        mail-request: public key

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Vincent Zoc » Wed, 07 Sep 1994 21:02:21



>I want to use some grep command to match lines that contain
>some word and NOT followed by another.
>Examples:
>    [1]    ^foo$
>    [2]    ^foobar$
>    [3]    ^foo foobar$
>    [4]    ^fooba$

>I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>4 would match. (line 3 has a foo NOT followed by bar)

>Question:
>    How should I do this?
>    I tried a few things but did not succeed. (I rtfm, the Unix FAQ
>    and O'Reilly's Unix in a Nutshell I believe)
>    This may not matter but I try to do this on AIX 3.2.5

With help I came to the following:

egrep 'foo($|[^b]|b$|b[^a]|ba$|ba[^r])' file.txt

(Elaborated)

Vincent

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Edgar R. All » Wed, 14 Sep 1994 07:20:32




>:-Examples:
>:-    [1]    ^foo$
>:-    [2]    ^foobar$
>:-    [3]    ^foo foobar$
>:-    [4]    ^fooba$
>:-
>:-I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>:-4 would match. (line 3 has a foo NOT followed by bar)
>:-
>: Negating a regular expression is tricky business.  For this relatively
>: easy example, you need something like:
>:

>It's much easier to grep twice:

>grep foo filename | grep -v foobar

Sorry.  That misses line number 3

A single 'grep -v foobar' will do as well. Which is almost what he wants.

Try:

        grep -v '^foobar$' Examples

On to the next wave...

        Ed Allen

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Harald Hanche-Ols » Sat, 17 Sep 1994 00:33:02



>>> :-Examples:
>>> :-    [1]    ^foo$
>>> :-    [2]    ^foobar$
>>> :-    [3]    ^foo foobar$
>>> :-    [4]    ^fooba$
>>> :-
>>> :-I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>>> :-4 would match. (line 3 has a foo NOT followed by bar)
>>> :-

Seems to me you could do it with sed:

sed -ne '/foo/{h;ba;}
         d
         :a
         s/foobar/+/g
         /foo/{x;p;}'

does the job just fine.  Amazing what sed will do for you...

- Harald

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Dr. Reinhard Corr [RHR » Fri, 16 Sep 1994 17:13:54



>>:-Examples:
>>:-    [1]    ^foo$
>>:-    [2]    ^foobar$
>>:-    [3]    ^foo foobar$
>>:-    [4]    ^fooba$
>>:-
>>:-I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>>:-4 would match. (line 3 has a foo NOT followed by bar)
>>:-
>>: Negating a regular expression is tricky business.  For this relatively
>>: easy example, you need something like:
>>:

>>It's much easier to grep twice:

>>grep foo filename | grep -v foobar

>Sorry.  That misses line number 3
>A single 'grep -v foobar' will do as well. Which is almost what he wants.
>Try:
>    grep -v '^foobar$' Examples
>On to the next wave...
>    Ed Allen

But what about a line "abc foobar"
gawk might help:

#!/bin/ksh

echo foo         > tt
echo foobar     >> tt
echo foo foobar >> tt
echo fooba      >> tt
echo abc foobar >> tt
echo abc        >> tt

gawk '{ if ( $0 ~ /foo/ ) \
           { \
           if ( $0 !~ /foobar/ ) \
              { print $0 } \
           else { \
              line = $0; \
              i = 1; \

              if ( line ~ /foo/ ) { print $0 } \
              } \
           } \
      }' tt

R. Corr

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by David W. Tamk » Sat, 17 Sep 1994 11:59:09




| Seems to me you could do it with sed:
|
| sed -ne '/foo/{h;ba;}
|          d
|          :a
|          s/foobar/+/g
|          /foo/{x;p;}'

Good method.  If you're laboring with a sed that doesn't support semicolons,
though, you can write the same logic this way:

  sed 'h
       s/foobar/+/g
       /foo/!d
       x'

You could also use 'g' instead of 'x' at the end.

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by David W. Tamk » Mon, 19 Sep 1994 05:12:21



|    The solution is :
|
|  sed 's/foobar/hooops/g' <filename> | grep foo | sed 's/hooops/foobar/g'

You can do it in one call to sed and fork one program instead of three:

  sed -e 's/foobar/hooops/g' -e '/foo/!d' -e 's/hooops/foobar/g'

assuming, as your suggestion does, that "hooops" doesn't occur in the input.
To get around even that assumption,

  sed -e h -e 's/foobar/hooops/g' -e '/foo/!d' -e g

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by d.lacro » Sun, 18 Sep 1994 03:35:14





>>:-Examples:
>>:-    [1]    ^foo$
>>:-    [2]    ^foobar$
>>:-    [3]    ^foo foobar$
>>:-    [4]    ^fooba$
>>:-
>>:-I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>>:-4 would match. (line 3 has a foo NOT followed by bar)
>>:-

   The solution is :

 sed 's/foobar/hooops/g' <filename> | grep foo | sed 's/hooops/foobar/g'

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Janet Rosenba » Sun, 18 Sep 1994 04:48:22





>>:-Examples:
>>:-    [1]    ^foo$
>>:-    [2]    ^foobar$
>>:-    [3]    ^foo foobar$
>>:-    [4]    ^fooba$
>>:-
>>:-I want to grep on 'foo' NOT followed by 'bar'. So line 1, 3 and
>>:-4 would match. (line 3 has a foo NOT followed by bar)
>    grep -v '^foobar$' Examples

this assumes that foobar is by itself, does not work for:

^splat foobar$

here is an awk statement which does what you want:

awk '$0 ~ /foo/{
        if(($0 ~ /foobar/) && ($0 ~ /foo[^b]/)) print $0;
        if($0 !~ /foobar/) print $0;
        }' testgrep

a bit unwieldy, though, I admit.

I do not know if grep can accomodate conditionals, which is the problem
we run into.

is there regexp syntax similar to the use of [^c] which matches all
non-c's?  

if such syntax existed, the following statement would work:

grep '/foo\[^bar]\/' testgrep

where \[ and \] are grouping symbols like \( and \) and ^ tells it to
look for anything which is not bar that follows foo.

but I suppose I just have highly irregular dreams...  :)

Janet

--

 
 
 

Q: grep 'foo' NOT followed by 'bar'

Post by Gaumond Pier » Sat, 24 Sep 1994 08:52:58




>: about the problem of writing a regexp to match foo not followed by
>: bar, someone wrote
>:
>:  > here is an awk statement which does what you want:
>:
>:
>:  > Yes ... a language with regular expressions AND conditionals (such as
>:  > awk or perl) is needed to do this, because there don't seem to be
>:  > any regular expression parsers which can handle negative matches of
>:  > groups of characters.
>:
>: Well, it's not strictly true.
>:
>:   egrep 'foo$|foo[^b]|foob[^a]|fooba[^r]'
>:
>: should work, but this sort of solution quickly becomes unwieldy if the
>: `bar' part becomes longer, to put it mildly.  So in a practical rather
>: than a theoretical sense, Lloyd is absolutely right.
>:
>: - Harald

>egrep foo | egrep -v bar should work. Of course it doesn't check to see
>if bar is immediately following foo. If you want to check just that
>do egrep foo | egrep -v foobar.

>Sriram


With `sed':

   sed -n -e '/foobar/d' -e '/foo/p' file >out

 
 
 

1. Q: grep 'foo' NOT followed by 'bar'

:   egrep 'foo$|foo[^b]|foob[^a]|fooba[^r]'
:
: should work, but this sort of solution quickly becomes unwieldy if the
: `bar' part becomes longer, to put it mildly.  So in a practical rather
: than a theoretical sense, Lloyd is absolutely right.

In Perl 5, this is simply /foo(?!bar)/.

Larry Wall

2. AD: AWK Class, Seattle 8/22-23

3. sed '/foo/a bar' does not work in a script

4. How does Ultra5 EIDE drive perform?

5. /kernel: arp: 'foo' moved from 'bar' to 'baz' on 'whatever'

6. ANNOUNCE: binutils-1.9l.tar.Z is on tsx-11

7. grep octal value (grep '\0145' /tmp/test) doesn't work !!

8. Network configuration problem

9. 'echo "some text" |read foo' results in empty $foo

10. 'diff' option like 'grep -q'?

11. Combining 'find' and 'grep' or searching in general

12. "Can't load library 'foo'" messages

13. 'gcc foo.c -g -lX11' don't work?!?