KaizenSoze
KaizenSoze

Reputation: 531

Vim: How to delete the same block of text over the whole file

I'm reviewing some logs with Java exception spam. The spam is getting is making it hard to see the other errors.

Is is possible in vim to select a block of text, using visual mode. Delete that block every place it occurs in the file.

If vim can't do it, I know silly question, vim can do everything. What other Unix tools might do it?

Upvotes: 3

Views: 751

Answers (4)

benjifisher
benjifisher

Reputation: 5112

Based on our discussion in the comments, I guess a "block" means several complete lines. If the first and last lines are distinctive, then the method you gave in the comments should work. (By "distinctive" I mean that there is no danger that these lines occur anywhere else in your log file.)

For simplifications, I would use "ay$ to yank the first line into register a and "by$ to yank the last line into register b instead of using Visual mode. (I was going to suggest "ayy and "byy, but that wold capture the newlines)

To be on the safe side, I would anchor the patterns: /^{text}$/ just in case the log file contains a line like "Note that {text} marks the start of the Java exception." On the command line, I would use <C-R>a and <C-R>b to paste in the contents of the two registers, as you suggested.

:g/^<C-R>a$/,/^<C-R>b$/d

What if the yanked text includes characters with special meaning for search patterns? To be on the really safe side, I would use the \V (very non-magic) modifier and escape any slashes and backslashes:

:g/\V\^<C-R>=escape(@a, '/\')<CR>\$/,/\V\^<C-R>=escape(@b, '/\')<CR>\$/d

Note that <C-R>= puts you on a fresh command line, and you return to the main one with <CR>.

It is too bad that \V was not available when matchit was written. It has to deal with text from the buffer in a search pattern, much like this.

Upvotes: 1

Nikita Kouevda
Nikita Kouevda

Reputation: 5746

Vim

To delete all matching lines:

:g/regex/d

To only delete the matches themselves:

:%s/regex//g

In either case, you can copy the visual selection to the command line by yanking it and then inserting it with <C-r>". For example, if your cursor (|) is positioned as follows:

hello wo|rld

Then you can select world with viw, yank the selection with y, and then :g/<C-r>"/d.

sed

To delete all matching lines:

$ sed '/regex/d' file

To only delete the matches themselves:

$ sed 's/regex//g' file

grep

To delete all matching lines:

$ grep -v 'regex' file

grep only operates line-wise, so it's not possible to only delete matches within lines.

Upvotes: 2

Peter Rincker
Peter Rincker

Reputation: 45087

Sounds like you are looking for the :global command

:g/pattern/d

The :global command takes the form :g/{pat}/{cmd}. Read it as: run command, {cmd}, on every line matching pattern, {pat}.

You can even supply a range to the :delete (:d for short) command. examples:

:,+3d
:,/end_pattern/d

Put this togehter with the :global command and you can accomplish a bunch. e.g. :g/pat/,/end_pat/d

For more help see:

:h :g
:h :d
:h :range

Upvotes: 3

mamdouh alramadan
mamdouh alramadan

Reputation: 8528

you can try this in vim

:g/yourText/ d

Upvotes: 1

Related Questions