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?

2
  • Just wondering: is there a reason you need to delete them in a specific order?
    – D. Ben Knoble
    Apr 18 '20 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 '20 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.
1
  • With no visual mode: :%norm WD and :%norm dt x Apr 17 '20 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.

1
  • Had me laughing with the regex belts :)
    – D. Ben Knoble
    Apr 18 '20 at 13:00
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

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.