25

With grep I can do a grep -v "my search" to get all the lines without "my search".

With sed I can sed '/baz/!s/foo/bar/g' to find replace text on lines with out "baz".

Is there a way to do the same thing in Vim? And is it possible to do it without "s///" syntax, and only using the "/" search syntax?

4 Answers 4

37
:g/pattern/

matches all the lines were pattern is found.

:v/pattern/

does the opposite. See :h global for more details.

You can use it like this:

:v/pattern/norm Ipattern not found - <CR>

to prepend "pattern not found - " to every line that doesn't have "pattern" or

:v/pattern/s/nrettap/pattern

to replace "nrettap" with "pattern" on every line that doesn't have "pattern".

Contrived examples, yes.

1
  • I lol'd on "nrettap".
    – UncleZeiv
    Jan 30, 2012 at 14:44
13

To search for the lines not containing foo, for example, do:

/^\(\(.*foo.*\)\@!.\)*$

Source: http://vim.wikia.com/wiki/Search_for_lines_not_containing_pattern_and_other_helpful_searches

2
  • 2
    I did not know about the \@ directive that lets you reference the previous atom in search. Very useful.
    – nelaaro
    Jan 30, 2012 at 14:19
  • 1
    Even if correct, this is really costly.
    – Benoit
    Jan 30, 2012 at 17:25
3

Using the :v commandEdit The traditional approach to find lines not matching a pattern is using the :v command:

:v/Warning/p

A neat trick when working with a large log file where you want to filter out as many irrelevant lines as possible before you get started on your real search is to save the file under a temporary name and delete all non-matching lines there:

:sav junk.log
:v/warning/d

You are now are editing a clone of your original file with all lines not matching "warning" removed and you can edit it at will.

Ref: https://vim.fandom.com/wiki/Search_for_lines_not_containing_pattern_and_other_helpful_searches

0

Another approach is doing "external grep"; from the manual (:help :grep):

5.2 External grep

Vim can interface with "grep" and grep-like programs (such as the GNU
id-utils) in a similar way to its compiler integration (see |:make| above).

                                *:gr* *:grep*
:gr[ep][!] [arguments]  Just like ":make", but use 'grepprg' instead of
            'makeprg' and 'grepformat' instead of 'errorformat'.
            When 'grepprg' is "internal" this works like
            |:vimgrep|.  Note that the pattern needs to be
            enclosed in separator characters then.
            If the encoding of the program output differs from the
            'encoding' option, you can use the 'makeencoding'
            option to specify the encoding.

                                *:lgr* *:lgrep*
:lgr[ep][!] [arguments] Same as ":grep", except the location list for the
            current window is used instead of the quickfix list.

For me, grepprg is set to the default (see with :set grepprg) that uses the external grep, and so I could do

:grep -v 'my_pattern' %

where % refers to the current file's name (see :help :_%).

After this, one can use :copen or :lopen to look up the results in the quickfix or location lists (depending whether :grep or :lgrep has been used, respectively).

NOTE

The external grep will always work on the saved file, and not on the buffer. Keep that in mind when getting inconsistent results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.