2

Here is a problem I am able to solve in Sublime in seconds but has me stumped in Vim:

Given text like this:

bob@bobshop.com Bob Potato
peter@petershop.co.uk Peter Carrot
thomas.cucumber@thomasstore.org Thomas Cucumber

I would like to delete either all the names in one go, and then the email addresses, or all the email addresses and then the names.

I'm hoping there is a way that doesn't require 10th Dan Regex skills?

  • Just wondering: is there a reason you need to delete them in a specific order? – D. Ben Knoble Apr 18 at 13:01
  • 1
    @D.BenKnoble no, like I said either order. Or do you mean why in one lot, and then another? If the latter, it's so I can paste them into the correct columns of a spreadsheet. :) – Ben Frain Apr 18 at 13:40
2

To delete all emails first:

vip:norm! dW

  • vip select paragraph
  • :norm! dW execute normal mode commands: delete WORD

Then you end up having only names -- delete them as usual I guess?

To delete all names first:

vip:norm! WD

  • vip select paragraph
  • :norm! WD execute normal mode commands: move cursor 1 WORD and delete to the end of line.
| improve this answer | |
  • With no visual mode: :%norm WD and :%norm dt x – SergioAraujo Apr 17 at 21:47
1

1st Dan needed to delete the names. The delimiter is the first space. So delete everything from the first space to end of line:

s/ .*$//

To delete the emails, a 2nd Dan is needed. Delete any non-space and the first space from the beginning of the line:

s/^[^ ]* //

Note: This answer assumes, that the delimiter is a single space character. If the delimiter between the email and the name is a <tab> or multiple spaces or any combination of it, we have to move to the 3rd Dan:

s/\s.*$//

This deletes from the first whitespace (be it a space or a tab) till the end of line.

s/^\S*\s\+//

This deletes from the beginning of the line (^) all non-whitespace characters (\S*) including the following one or more whitespaces (\s\+).

See :help /\s, :help /^ and :help /\+.

Now ranges:

The simplest case is if you want to act on the entire file, just use % like:

:%s/ .*$//

If it is only a part of the file, the easiest way is to visually select the lines and then hit : and enter one of the substitution commands from above.

| improve this answer | |
0

The easiest way to do that would be to use a macro.

Given you are on the 1st line 1st col:

" To delete the emails:
qa0dWjq2@a

" To delete the names:
qa0ElDjq2@a

Though I would admit that it's far from being as intuitive as Sublime or VScode with the multi cursors.


Or, as you mentioned, we can use holy regex:

" To delete the emails:
s/^\S\+//g

" To delete the names:
s/^\S\zs\s.*$//g 

Or, you could use the norm command:

" To delete the emails:
vip:norm!dW

" To delete the names:
vip:norm!ElD
| improve this answer | |

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.