开发者

Find first non-matching line in VIM

It happens sometimes that I have to look into various log and trace files on Windows and generally I use for the purpose VIM.

My problem though is that I still can't find any analog of grep -v inside of VIM: find in the buffer a line not matching given regular expression. E.g. log file is filled with lines which somewhere in a middle contain phrase all is ok and I need to find first line which doesn't contain all is ok.

I can write a custom function for tha开发者_运维问答t, yet at the moment that seems to be an overkill and likely to be slower than a native solution.

Is there any easy way to do it in VIM?


I believe if you simply want to have your cursor end up at the first non-matching line you can use visual as the command in your global command. So:

:v/pattern/visual

will leave your cursor at the first non-matching line. Or:

:g/pattern/visual

will leave your cursor at the first matching line.


you can use negative look-behind operator @<!

e.g. to find all lines not containing "a", use /\v^.+(^.*a.*$)@<!$

(\v just causes some operators like ( and @<! not to must have been backslash escaped)

the simpler method is to delete all lines matching or not matching the pattern (:g/PATTERN/d or :g!/PATTERN/d respectively)


I'm often in your case, so to "clean" the logs files I use :

:g/all is ok/d

Your grep -v can be achieved with

:v/error/d

Which will remove all lines which does not contain error.


It's probably already too late, but I think that this should be said somewhere.

Vim (since version about 7.4) comes with a plugin called LogiPat, which makes searching for lines which don't contain some string really easy. So using this plugin finding the lines not containing all is ok is done like this:

:LogiPat !"all is ok"

And then you can jump between the matching (or in this case not matching) lines with n and N.

You can also use logical operations like & and | to join different strings in one pattern:

:LP !("foo"|"bar")&"baz"

LP is shorthand for LogiPat, and this command will search for lines that contain the word baz and don't contain neither foo nor bar.


I just managed a somewhat klutzy procedure using the "g" command:

:%g!/search/p

This says to print out the non-matching lines... not sure if that worked, but it did end up with the cursor positioned on the first non-matching line.

(substitute some other string for "search", of course)


You can search with following line and press n to jump to the first non-matching line

^\(.*all is ok\)\@!.*$

Breakdown of operators:

^           -> means start of the line
\( and \)   -> To match a whole string multiple times, it must be grouped into one item. This is done by putting "\(" before it and "\)" after it.
\@!         -> Matches with zero width if the preceding atom does NOT match at the current position.
.*          -> Matches any character repeated 1 or more times
$           -> end of the line

Here is sample animation how it works. For simplicity I searched for word apple.

Find first non-matching line in VIM


You can iterate through the non-matches using g and a null substitution:

:g!/pattern/s/^//c

If you reply "n" each time you wont even mark the file as changed.

You need ctrl-C to escape from the circle (or keep going to bottom of file).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜