3

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?

Sagar Jain
  • 6,261
  • 10
  • 40
  • 73
KaizenSoze
  • 511
  • 4
  • 16
  • What sort of "block" do you mean? If it is a string of consecutive characters in a single line, then you already have several answers below. If you mean the sort of thing that you can select in Visual-block mode, spanning more than one line, then it is more complicated. – benjifisher Apr 18 '14 at 16:47
  • Thanks to the answer below and this question, http://stackoverflow.com/questions/101258/in-vim-is-there-a-way-to-paste-text-in-the-search-line, I figured out how to do it. Benji, a stack trace can be 1 to N lines with various whitespace, usually tabs. 1. Visual select the top line of the stack 2. Yank to buffer a 3. Visual select the bottom line of the stack 4. Yank to buffer b 5. g:/R>a/,/R>b/d Yanking the whole block of text did not work for me because of white space, newlines. The pattern yanked into the search command would not match the file text. Any simplifications? – KaizenSoze Apr 18 '14 at 17:03

4 Answers4

3

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
Peter Rincker
  • 39,385
  • 8
  • 64
  • 92
  • Downvoted because these methods don't do what the OP asked for help with. – Mike Diehn May 14 '19 at 20:06
  • 1
    @MikeDiehn You realize that OP accepted this answer, right? And I'd encourage you to review https://stackoverflow.com/help/privileges/vote-down specifically "Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect." and "Down-voting should be reserved for extreme cases. It's not meant as a substitute for communication and editing." – Nikita Kouevda May 14 '19 at 23:59
  • Hi, Nikita! I'm so sorry! I had *not* read that guidance, at least not recently enough to have been aware of it when I was down voting here! Thank you very much for calling my attention to my mistake. If I can undownvite, I will. – Mike Diehn May 16 '19 at 12:18
2

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.

Nikita Kouevda
  • 4,830
  • 2
  • 25
  • 41
  • I'm sorry for the downvote, I hadn't read the explanation about when to use them and didn't realize how drastic they are! I'd undo it if I could. – Mike Diehn May 16 '19 at 12:25
1

you can try this in vim

:g/yourText/ d
mamdouh alramadan
  • 7,663
  • 5
  • 32
  • 52
  • I'm sorry for the downvote, I hadn't read the explanation about when to use them and didn't realize how drastic they are! I'd undo it if I could. – Mike Diehn May 16 '19 at 12:21
1

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.

benjifisher
  • 4,729
  • 13
  • 17