Peter Brooks
Peter Brooks

Reputation: 389

Find all lines that don't match a regular expression (regex) - a 'negative match'

How can you match everything that doesn't match a pattern?

Trying with sed gives very awkward looking results.

If we want to replace this file:

The quick brown fox leaps over the lazy dog.  
The swift brown fox leaps over the lazy dog.  
The swift green frog leaps over the lazy fox.  
The quick yellow dog leaps over the lazy fox.  


with:

The quick brown fox jumps over the lazy dog.    
The swift brown fox jumps over the lazy dog.    
The quick yellow dog jumps over the lazy fox.    


What is an elegant way to do this?

Upvotes: 2

Views: 5353

Answers (4)

Claes Wikner
Claes Wikner

Reputation: 1517

Is it something like this you are looking for?

awk '!/green/{$5="jump"; print}' file

The quick brown fox jump over the lazy dog.
The swift brown fox jump over the lazy dog.
The quick yellow dog jump over the lazy fox.

Upvotes: 2

Tom Fenech
Tom Fenech

Reputation: 74685

If you just want to print lines that don't match your regular expression, grep -v is the correct tool for the job.

You can do a simple replacement in sed on lines that don't match like this:

sed -n '/frog/! s/leaps/jumps/ p' file

-n means don't print, ! negates the match, s substitutes then p prints

For more complex processing, I'd use awk (I've showed the equivalent to the sed example here):

awk '!/frog/ { sub(/leaps/, "jumps"); print }' file

Upvotes: 4

Peter Brooks
Peter Brooks

Reputation: 389

I would recommend using awk.

Your data is kept in 'input_file':

The quick brown fox leaps over the lazy dog.  
The swift brown fox leaps over the lazy dog.  
The swift green frog leaps over the lazy fox.  
The quick yellow dog leaps over the lazy fox.  


You want to match lines that don't match frog. Here is the awk script. Notice that we put the sed regular expression (regex) in the string cmd replace this with any sed regex you want (NB: You really do need the close(cmd)):

!/frog/  {cmd="echo " $0 "|sed 's/leaps/jumps/'" ;cmd|getline output;print output;close(cmd)}


Put the above into the script 'match_all_but_frog.awk'. Then:

awk -f match_all_but_frog.awk <input_file


output:

The quick brown fox jumps over the lazy dog.  
The swift brown fox jumps over the lazy dog.  
The quick yellow dog jumps over the lazy fox.  



If you want to match 'Frog','Frogs' or 'FROGS' as well as 'frog':

BEGIN {
IGNORECASE = 1;
      }
!/frog|frogs/  {cmd="echo " $0 "|sed 's/leaps/jumps/'" ;cmd|getline output;print output;close(cmd)}

Upvotes: -3

Esteban
Esteban

Reputation: 1815

You can just use a grep -Ev "regex pattern" /path/to/yout/file and it will match every line that does not match the regex pattern

Upvotes: 4

Related Questions