How to apply a regex to multiple lines? - vim

let's say I want to apply the following to lines 60 through 80 in a file that I am editing in vim.
:s/{/ {/
Is there a way to do this?
Thanks!

You can prefix your search command with a line range, e.g.
:60,80s/{/ {/
If you want the change to apply from line 60 and forward use :60,s. If you want to change the lines from current to 80 do: :,80s. You can even do :.+3,80s to apply the search between current line + 3 and line 80.

You can use several type of ranges as described here. And here are the official docs.

You can also mark the first line of the section that you want to apply the regex to with the m (mark) command. Then move the cursor to the last line of the section. Then the regex command becomes:
:'a,. s:/foo/bar/
which says, from the line marked 'a' to the current line, substitute foo with bar.

Related

How to express the line before the last in vim?

How to express the line before the last in vim?
It is clear that $ is the last line.If there is a article which contain 20 llines,$ is equal 20 here, how about the line before the last,it is 19 ,how to write it such as $-1 ,can we create a expression 19=$-1??
If you want to reference the last minus n line in command line you can use $-n.
For instance, to go to the second to last line:
:$- # same as :$-1
You can use it to define a range:
:,$-10 # from the current line to 10 lines before the last one
It is a bit unclear what you are asking.
A solution to reach the penultimate line is using something like :
:normal Gk
that you can map in a user defined command.

Vim replacing in inverse direction

How can I replace in Vim from current line in inverse direction (upward) (for searching I'm using ?textToFind, for replacing from current position :,$s/a/b)?
You can use backwards range with :s command.
If you want to do replacement from line 1 to your current line, you can do :,1s/foo/bar/g vim will ask you if you are sure to apply command on a backwards range, press y
You can also do something like :,-3s/foo/bar/ to do replacement from current line (n) till line n-3
The range used for s// (and other Ex commands) can be made of:
line numbers, 1,23
relative lines, -5,+17
line shortcuts, .,$
marks, 'a,'g
searches, ?foo?,/bar/
or any combination of the above items, ?foo?,'g, 23,$, +5,/bar/, .,/baz/+6…
A range extending from the first instance of foo before the cursor to the last line could look like that:
?foo?,$
A range extending from the first instance of foo before the cursor to the current line could look like that:
?foo?,.
and even be shortened to:
?foo?,
There's no built-in way to visit the lines from the end to the beginning. Vim will issue a Backwards range given, OK to swap? query, and turn around the range if confirmed. The only way is by manually specifying the individual lines in reverse order:
:.s/a/b | .-1s/a/b | .-2s/a/b | ...
Of course, you can write a custom command for that.
If you also require reverse replacement inside a line (all of that only makes sense with the confirm flag, doesn't it?), you're out of luck with :substitute.

How to replace current string line with another line in vim?

I'd like to replace current string line with another (for example the another line is placed in 5 lines above current line). I can do it with a pair of commands
dd
:-5t-1
Is there the shorter way to obtain same goal?
dd
:-5t-1
is already pretty short if you ask me. But you can squeeze everything into a one-liner:
:d|-5t-1
and remove the 1 because it's implied by -:
:d|-5t-
Barring making a custom command or mapping I don't see how you could make it shorter.
:-5y<CR>Vp
is it shorter?
if you need do that really often, add this into your vimrc:
command! -range R d|<line1>,<line2>t-
then you can just do :-5R replace current line with -5 line
or 2,4R to cp line 2-4 (3 lines) to current line, and replace current line.
If you don't mind a plugin, my LineJuggler plugin offers a ]r command (and many more):
]r Fetch the line [count] visible lines above the current line and replace the current line with it.
With it, your example would be the short and easy 5]r
In addition, the companion LineJugglerCommands plugin now offers a similar :Replace Ex command. Again, your example would be
:Replace -5

How to append every third line in Vim?

I'm not at all familiar with Vim but I'm working with large text files (~1G) and my standard text editors weren't cutting it.
My files are currently in this format:
Arbitrary_title_of_sequenceA
SEQ1SEQ1SEQ1SEQ1
SEQ2SEQ2SEQ2SEQ2
Arbitrary_title_of_sequenceB
SEQ1SEQ1SEQ1SEQ1
SEQ2SEQ2SEQ2SEQ2
I need a convenient way of appending the "SEQ2" line to the "SEQ1" line like so:
Arbitrary_title_of_sequenceA
SEQ1SEQ1SEQ1SEQ1SEQ2SEQ2SEQ2SEQ2
Arbitrary_title_of_sequenceB
SEQ1SEQ1SEQ1SEQ1SEQ2SEQ2SEQ2SEQ2
Considering the size of these files, doing each line separately isn't really an option. Any help would be much appreciated!
What about providing a correct sample to begin with?
:g/SEQ1/norm Jx
does what I think you want.
:g/SEQ1 is the :global command which allows you to act on each line containing the pattern SEQ1. See :help :global.
norm is the :normal command that you use to perform a normal mode command, here on every line matched by :g/SEQ1. See :help :normal.
After that comes the normal command in question:
J is used to join the current line with the line below.
x is used to remove the <Space> automatically added by Vim.
:1,$s/\(.*\n\)\(.*\)\n\(.*\n\)/\1\2\3/
1,$ -> range is all file
s/PAT1/PAT2/ -> substitute PAT1 with PAT2
.* -> match any character except new line
\n -> match new line
\(PAT1\) -> capture/remember the string that matched PAT1
\1,\2,\3 -> refers to the captured string for captures in order
Also using sed instead of vim should be faster:
sed -i 'n;N;s/\n/ /' input_file
This can be summarized as:
Read a line
Read another line and print previous line (n)
Read another line and append it to the previous line (N)
find the first newline and change it to space (s/\n/ /)
print the line (or merged lines)
I think romainl's solution is the best if you have a reliable "SEQ1" pattern you can grab onto. If not and you want to literally join every third line, you could easily do this with a macro:
qqjJxjq
Hit G to see how many lines are in the file and just repeat the macro that many times (it doesn't matter that it's higher than you need). So if the file was 1000 lines you could do 1000#q. This kind of solution is easy to remember and integrate into your normal workflow.

Remove all arbitary spaces before a line in Vim

I'v written a plugin where it comes to parsing a XML tag. The content inside the tag is indented and when i copy the parsed string into the file it's gettting like:
Example line
This is part of the parsed line
Thats goes one
End of line
What I want is to remove all spaces in front of these lines, the final text should be
Example line
This is part of the parsed line
Thats goes one
End of line
I've tried to use = but it doesn't work the way I want. How can I do that with minimal key strokes ?
To format a line to the left I use :left. Use this format an entire file:
:%le
A simple search/replace s/^\s*// should do the trick, but it's probably not the minimal version.
Personally I would visually select the lines with V, then use 99< to push the text as far left as it could go.
Just type d followed by w followed by j at the beginning of each line.
How about this:
:%s/^ *//
Or are you looking for a vim-script solution?
To remove initial spaces and tabs at specified line numbers (E.g. from lines 5 to 10),
:5,10s/^\s*//
Yet another way to achieve this is using the the normal command :h :normal-range
:%norm d^
This goes to column 0 in each line (%) and deletes (d) to the first non-white character(^).
This is slightly more to type as the accepted answer, but allows for easy extension if you have a more complex scenario in mind, such as additional un-commenting or so:
:%norm d^I#
Resulting in:
#Example line
#This is part of the parsed line
#Thats goes one
#End of line
The search/replace suggested by Lukáš Lalinský or the %le approach in the wikia page is probably the way I'd do it, but as another alternative you could also do:
:%< 99
As a quick way to shift the whole file (%) 99 times to the left.
Remove all consecutive spaces: :%s/ */ /g
It was useful to me to go from:
$screen-xs-min: 480px;
$screen-sm-min: 768px;
$screen-md-min: 992px;
$screen-lg-min: 1200px;
To:
$screen-xs-min: 480px;
$screen-sm-min: 768px;
$screen-md-min: 992px;
$screen-lg-min: 1200px;

Resources