Computing.Net > Forums > Unix > Negate a Regular Expression?

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

Negate a Regular Expression?

Reply to Message Icon

Name: caffiene
Date: October 8, 2004 at 07:38:48 Pacific
OS: Win2K
CPU/Ram: P4 2Ghz
Comment:

Is there any way to negate a regular expression so that a search finds everything that does NOT match the pattern?

Also, is there any way to negate a backreference in order to see if two words do NOT match within a line?
For example, the first line has two matching words with a space in between and the second has two non-matching words. The search would match the second one.

Bob Bob
Tom Cal

If either of these are possible, I think they can accomplish many of the same tasks.

Thank ahead of time,

Carl




Sponsored Link
Ads by Google

Response Number 1
Name: Jim Boothe
Date: October 10, 2004 at 08:43:01 Pacific
Reply:

For grep, the -v option will negate (or reverse) the result set.

grep red
grep -v red

grep -e red -e blue -e pink
grep -ve red -e blue -e pink

sed can negate a pattern with !  The first sed below outputs all lines containing "red", while the second outputs the opposite set of lines.

sed /red/!d
sed /red/d

Or we can negate at a higher level.  sed -n will suppress sed's default action of outputting each (non-deleted) line.  Now, we can print just the ones we want.  The following two seds give identical results as the previous two seds:

sed -n /red/p
sed -n /red/!p

To locate lines that have non-matching successive words, you would not negate a back-reference.  Locate lines that DO have matching successive words and take appropriate action.  The following (requires GNU sed) locates lines containing a string followed by the identical string, separated by one or more spaces.  In this case, it deletes the lines, thus giving you all lines that do not.

sed '/\([^ ][^ ]*\)  *\1/d'

But the code above is not "word" oriented.  It would suppress, for example "Robert Roberta" because it would see the string Robert followed by Robert.

The following code will do the same, word-oriented, insisting that the duplicated string is delimited by spaces or beginning of line or end of line (maybe someone will post a simplified version of this):

sed '
/\(^[^ ][^ ]*\)  *\1$/d
/\(^[^ ][^ ]*\)  *\1 /d
/\( [^ ][^ ]*\)  *\1$/d
/\( [^ ][^ ]*\)  *\1 /d
' myfile

If you want to limit your duplicate check to words of known position, awk would be best for that.  The following awk will print each line where word3 does not equal word4:

awk '$3!=$4' myfile

And with just a bit more coding, awk can confirm if the line contains (or does not contain) two consecutive identical words.


0

Response Number 2
Name: caffiene
Date: October 12, 2004 at 05:46:23 Pacific
Reply:

Thanks for the detailed response! I need to learn more about grep, sed, and awk, but what you have told me works for what I'm doing now. So far, I've just been using vi.

Thanks again,

Carl


0

Sponsored Link
Ads by Google
Reply to Message Icon

Related Posts

See More







Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Unix Forum Home


Sponsored links

Ads by Google


Results for: Negate a Regular Expression?

How to negate a regexp with 'ls' www.computing.net/answers/unix/how-to-negate-a-regexp-with-ls/7058.html

Regular expression in awk www.computing.net/answers/unix/regular-expression-in-awk/6378.html

Regular expressions www.computing.net/answers/unix/regular-expressions/5690.html