vim (vi improved) is probably the most popular text editor in Linux systems. The main strengh of vim lies in the ability to use regular expressions to select and edit with a single command all lines that match a given text pattern.
But sometimes, the inverse is required: editing all lines that DO NOT match a text pattern. This is also possible in vim, as explained in this post.
As an example, let’s say we need to remove from a text file all lines that contain the word “property”. In vim, this is easily done with the “:g” command:
There is also a “:v” command that works the opposite as “:g”. Thus, to remove all lines that DO NOT contain the word “property”, we can use te command:
Naturally, we can use any other editing command instead of “d”. For instance, the following command can be used to insert the literal “NOT MATCHING ” at the start of each line that does not contain the word “property”.
:v/property/s/^/NOT MATCHING /
A slightly more complex case is that of selecting all lines that contain one of two (or more) substrings. For instance, to remove all lines that contain either the word “property” or the word “house”:
and, replacing “:g” with “:v”, the command will remove all lines that do not contain neither the word “property” nor the word “house”:
To match only lines that contain both words “house” and “property”, in any order, we can use the “\&” operator in the regular expression, as follows:
and, replacing “:g” with “:v”, the inverse is true: only lines that do not contain both words will be edited
Finally, we may need to select all lines that contain both words “house” and “property”, but do not contain any of the words “big” or “small”. The negation operator “\@!” can be used to construct this expression:
and replacing “:g” with “:v”, the lines selected would have been those that:
- do not contain “house” OR
- do not contain “property” OR
- do not contain contain neither “big” nor “small”
Using the “\v” modifier
In the regular expressions used in this post, the special characters “(“, “)”, “&”, “|” and “@” need to be escaped prepending the backslash character “\”.
This can be avoided using the “\v” modifier (not to be confused with the “:v” command). With this modifier, the expression is easier to read. For instance, the expression in the las example could be re-written as::