Ali
Ali

Reputation: 456

VIm for each line replace a word based on another word on the same line

how can I implement the following in VIM

substitute/regex_this_word/regex_with_another_word_from_the_same_line

e.g

select "ali" as name where _placeholder = _placeholder
union
select "sam" as name where _placeholder = _placeholder

after applying

:%s/_placeholder/anythin_between_quotation/

becomes

select "ali" as name where ali = ali
union
select "sam" as name where sam = sam

e.g2

select id, "_placeholder" as vul members_repeater/vul/none

after applying

:%s/_placehold/\=something_like_regexp(getline('.'),'regexp_pattern_to_select_everthing_after_/vul/")

becomes

select id, "none" as vul members_repeater/vul/none 

thanks

Upvotes: 1

Views: 342

Answers (3)

Kent
Kent

Reputation: 195039

:%s/_placeholder/\=split(getline("."),'"')[1]/g

this works in this case:

  • only one quotation part (replacement) in each line
  • the quotation part could be anywhere in this line

for example:

select "ali" as name where _placeholder = _placeholder
union
select "sam" as name where _placeholder = _placeholder
select _placeholder where _placeholder = _placeholder "foo"
select _placeholder where "bar", _placeholder = _placeholder

into

select "ali" as name where ali = ali
union
select "sam" as name where sam = sam
select foo where foo = foo "foo"
select bar where "bar", bar = bar

edit

\=split(getline("."),'"')[1]
 |  |      |
 |  |      +--- get current line text
 |  |
 |  +------ split the line with " as separator, pick the middle part ([1])
 |
 |
 +---- using expression replacement

new edit

so you can re-use the old routine :

:%s#_placeholder#\=split(split(getline("."),"vul/")[1]," ")[0]#g

this needs only one vul/ in your line, but there could be text after the keyword (with space as separator) something like:

select id, "_placeholder" as vul members_repeater/vul/none trashtrash

into

select id, "none" as vul members_repeater/vul/none trashtrash

see this example :

enter image description here

Upvotes: 4

Zulu
Zulu

Reputation: 9265

You can easily use sed if know it, it allow you to use extended regex:

example_with_no_link.txt:

from django.utils import unittest
from django.core import management
from app import subapp

vim command :

:%! sed -re "/django/ s/from (.*) import (.*)/from \2 import \1/"

This command does followings things :
1. :%!: Put all line in stdout
2. sed -re "/django/ : if there's 'django' in line
3. s/from (.*) import (.*)/from \2 import \1/ : reverse patterns in parenthesis

In sed, you catch your searched words with parenthesis and write them with \n.
The output is redirect to vim.

Upvotes: 1

Arthur Reutenauer
Arthur Reutenauer

Reputation: 2632

For these lines in particular, that would be

s/^\(.*\)"\([^"]*\)"\(.*\)_placeholder\ = _placeholder/\1"\2"\3\2 = \2/

Explanations: expressions in between matching pairs of \( and \) are captures in \1, \2, etc. Hence, one way to proceed here is to capture everything up to _placeholder, and there put it back. A little unreadable, admittedly.

That solution assumes there is only one expression in double quotes on each line.

Upvotes: 1

Related Questions