Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Globally append to line with matching term in vim

Tags:

vim

I am sure this is easy, I am just missing a character or two.

I need to search for a particular term in a file, and when I find it, I need to append something to that line. And I want to do that for EVERY line with the match.

To do it once, I can do this:

/Thing to find/s/$/ Stuff to append/

Easy. And if my "thing to find" were at the END of the line I could do this:

%s/\(Thing to find\)$/\1 Stuff to append/

To do the same thing on every matching line

But how do I do the first thing on every line?

I guess I could do

%s/\(Thing to find.*\)$/\1 Stuff to append/

But that feels clumsy and would make it more complicated if the thing to find were on a line more than once.

I am thinking there must be a way to just do my first search everywhere, but I am having trouble writing a concise enough description to google it.

So mighty Stackers, anyone want to nerd slap me with a two byte solution?

like image 814
Skip Huffman Avatar asked Jan 08 '13 14:01

Skip Huffman


3 Answers

The :g// command is what you're looking for — it runs a command on each line matching a pattern:

:g/Thing to find/ s/$/ Stuff to append/
like image 159
Smylers Avatar answered Nov 04 '22 21:11

Smylers


As mentioned, :g// is what you're after, but one further efficiency for your particular need is to run a normal command as part of the global. s is just one of a bunch of commands that :g// can take. You could also d(elete), j(oin), and pretty much whatever ex commands you can imagine.

Another useful one is norm(al), which can be used to execute any normal command. From the :help on :norm(al): "Commands are executed like they are typed."

So you could also achieve what you want with:

:g/Thing to find/norm Astuff to append

Let's say I'm duplicating my mysql config file for my test environment. I want to append _test to every line that starts with "database=", so:

g/^database=/norm A_test

The thing to remember is that Vim will execute everything after 'norm' as if you had typed it in. So no space between the A command and the text to be appended (or you will get an extra space in the output).

like image 30
Jangari Avatar answered Nov 04 '22 22:11

Jangari


:%s/green/bright &/g: Replace each "green" with "bright green" in the file.

&: substitute matched string. You can do anything you can imagine.

You can use the flag \v so we don't have to use as many escape characters.

append the parameter --no-startup-id after exec or exec_always

:%s/exec\(_always\)\?/& --no-startup-id/g

simplify it:

:%s/\vexec(_always)?/& --no-startup-id/g

like image 27
Delayless Avatar answered Nov 04 '22 22:11

Delayless